Reputation: 15327
I need help getting the broken part of this code working.
How do I tag dispatch two functions (that return different value-types) based on a string?
If the overall code can be simplified with the intent of dispatching with strings, please do make recommendations. TY.
Requirements:
CODE
#include <map>
#include <string>
#include <iostream>
struct Shape { };
struct Rectangle_Type : public Shape { using value_type=int; };
struct Circle_Type : public Shape { using value_type=std::string; };
Rectangle_Type Rectangle;
Circle_Type Circle;
static std::map<std::string,Shape*> g_mapping =
{
{ "Rectangle", &Rectangle },
{ "Circle", &Circle }
};
int tag_dispatch( Rectangle_Type )
{
return 42;
}
std::string tag_dispatch( Circle_Type )
{
return "foo";
}
int
main()
{
std::cerr << tag_dispatch( Circle ) << std::endl; // OK
std::cerr << tag_dispatch( Rectangle ) << std::endl; // OK
#define BROKEN
#ifdef BROKEN
std::cerr << tag_dispatch( (*g_mapping["Rectangle"]) ) << std::endl;
std::cerr << tag_dispatch( (*g_mapping["Circle"]) ) << std::endl;
#endif
}
Upvotes: 1
Views: 944
Reputation: 3510
C++ does not have dynamic dispatch. This is probably what you expect to happen. You can emulate it with dynamic_cast, but that's slow and not recommended. You could use a virtual function returning an enum for the type though.
class base
{
public:
virtual ~base() // Don't forget the virtual destructor if you want to inherit from it!
{}
enum type
{
a,
b,
};
virtual type get_type() const = 0;
};
class a : public base
{
public:
virtual type get_type()
{
return base::type::a;
}
};
class b : public base
{
public:
virtual type get_type()
{
return base::type::b;
}
};
Upvotes: 0
Reputation: 31952
Unless C++11 has changed this.. The problem is that you are dereferencing a Shape*
pointer, which means the resulting datatype (Shape&
) does not have a valid overload of tag_dispatch
.
You can do something like g_mapping["Rectangle"]->tag_dispatch()
. Or more cleanly rewrite as below.
std::string tag_dispatch( Shape& shape)
{
return shape->tag_dispatch();
}
This way you can support non Shape
objects with an identical interface. Both need you to make tag_dispatch
as a virtual function of Shape
as well.
Upvotes: 1