On 4/28/2016 2:39 PM, Jens Thoms Toerring wrote:
SNIP
> Mmmm, you are aware that you can't overload by return type?
> The compiler only takes different arguments into account when
> deciding what function to call, but not the type of what a
> function returns.
>
> So, having e.g.
>
> int foo(std::string const & str);
> double foo(std::string const & str);
>
> won't work.
I am. As far as I know the return type in derived is being defined by
the typename in base. Therefore, the return type is the same when the
template code is instantiated. At least that is what I am trying to
accomplish.
> And, if you have to overload everything from your base class,
> why make it a base class in the first place (instead of e.g.
> a member variable)? Just curious (and probably missing the
> point since I don't really know about the problem you're
> trying to solve;-)
> Regards, Jens
>
I will try to restate the problem:
I've got a file that is provided by Mickey Mouse on a daily basis and it
contains objects of type "Cheese" that he serialized to XML.
I've got a file that is provided by Megatron on a daily basis and it
contains objects of type "World Domination Plan" that he serialized to XML.
I want to have one interface type that I can use in my client program to
parse the "Cheese" or "World Domination Plan" in the same manner.
So, I've told a team to go and implement that actual parsing of "Cheese"
in a class derived from the common interface.
I've told another team to go and implement the actual parsing of "World
Domination Plan" in another class derived from the common interface.
Later on, I might get a file from Papa Smurf that contains "Recipe For
Mushroom Soup" that he serialized to XML. I'd like to be able to follow
the pattern then and not have to change my client code.
I can also easily swap out implementations to my interface in order to
provide proxy classes if I wish for unit testing code that is dependent
on the XML parsers.
I now have this code and it seems to work as expected, unless I am
missing something:
------------------------
// Standard Includes
#include <string>
namespace XMLParsing
{
template <typename T> class IXmlParser
{
public:
/// <summary>
/// Parses XML a string
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <returns></returns>
virtual T FromString(const std::string & xml) = 0;
/// <summary>
/// Parses XML from a file
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
virtual T FromFile(const std::string & path) = 0;
};
}
--------------------
// Project Includes
#include "IXmlParser.hpp"
// Domain Inludes
#include "DailyData.h"
// Standard Includes
#include <string>
namespace XMLParsing
{
class FocusXmlReader : public IXmlParser<Domain::Focus::DailyData>
{
public:
Domain::Focus::DailyData FromString(const std::string & xml);
Domain::Focus::DailyData FromFile(const std::string & path);
};
}
------------------
// Project Includes
#include "FocusXmlReader.h"
// Shared Library
#include "StringUtility.h"
// Standard Includes
#include <memory>
#include <sstream>
#include <string>
#include <stdexcept>
//------------------------------------------------------------------------------
const static std::string path = "C:\\Temp\\Focus\\07132014-4544-D.FTPQ";
//------------------------------------------------------------------------------
void ParseUsingPugiXml()
{
std::unique_ptr<XMLParsing::IXmlParser<Domain::Focus::DailyData> >
parser(new XMLParsing::FocusXmlReader());
Domain::Focus::DailyData dailyData = parser->FromFile(path);