1

我需要帮助让这段代码的损坏部分正常工作。

如何根据字符串标记调度两个函数(返回不同的值类型)?

如果可以简化整体代码以使用字符串进行调度,请提出建议。泰。

要求:

  1. 基于字符串的调度
  2. 矩形重载需要返回int,而Circle重载需要返回std::string
  3. 从 Rectangle_Type 到 int 和 Circle_Type 到 std::string 的映射是固定的并且在编译时是已知的。我的部分问题是 std::map 是一个运行时构造:我不知道如何使 std::string 到标记映射一个编译时构造。
  4. 如有必要,运行时解析是可以的:但是,调度必须允许基于解析到的枚举/类型的不同返回类型。

代码

#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
}
4

2 回答 2

1

除非 C++11 对此进行了更改。问题是您正在取消引用一个Shape*指针,这意味着生成的数据类型 ( Shape&) 没有有效的tag_dispatch.

你可以做类似的事情g_mapping["Rectangle"]->tag_dispatch()。或者更干净地重写如下。

std::string tag_dispatch( Shape& shape)
{
    return shape->tag_dispatch();
}

这样您就可以支持Shape具有相同接口的非对象。两者都需要您将tag_dispatch其作为虚拟功能Shape

于 2013-01-30T02:38:02.520 回答
0

C++ 没有动态调度。这可能是您期望发生的事情。您可以使用 dynamic_cast 模拟它,但这很慢且不推荐。不过,您可以使用为该类型返回枚举的虚函数。

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;
    }
};
于 2013-01-30T02:39:34.127 回答