c++ - 给定一组类,调用具有匹配方法参数的类

标签 c++ c++14

我有 2 个或更多类继承自一个父类。他们都重载了handle方法,但每个类的句柄方法都有不同的参数。

class CommandHandler {};

class FooCommandHandler : public CommandHandler
{
public:
  string handle(const FooCommand& c) { return c.getStringSomehow(); }
};

class BarCommandHandler : public CommandHandler
{
public:
  string handle(const BarCommand& c) { return c.getStringSomeOtherWay(); }
  string handle(const OtherBarCommand& c) { return c.youGetThePicture(); }
};

FooCommandHandler fooHandler;
BarCommandHandler barHandler;

我想要一个函数来评估哪些类具有正确的签名并调用它。这可能吗?

理想情况下,这将在编译时完成,并且它会 static_assert 恰好有一个匹配项。

给定签名template<typename C> string sendCommand(C c) :

sendCommand<BarCommand>(c)会调用barHandler.handle(c)

sendCommand<FooCommand>(c)会调用fooHandler.handle(c)

最佳答案

通常的函数重载适用于您的情况。你要签名template<typename C> string sendCommand(C c)所以模板参数是第一个函数参数的一种。然后定义:

string sendCommand(const FooCommand& c) {
    fooHandler.handle(c);
}
string sendCommand(const BarCommand& c) {
    barHandler.handle(c);
}

然后调用他们。此处甚至不需要模板。

如果你有很多命令和处理程序,你可以试试这个:

// We need a way to retrive handler by its type. Tuple is good for that.
std::tuple<FooCommandHandler, BarCommandHandler> handlers;

// Note the return type. If Handler on position handlerIndex does not have proper method, then instantiation will fail and, due to SFINAE, this function will just be ignored.
template<class Command, size_t handlerIndex = 0>
auto sendCommand(const Command& c) -> decltype(std::get<handlerIndex>(handlers).handle(c))
{
    return std::get<handlerIndex>(handlers).handle(c);
}

// Again, SFINAE technique. Compiler will stop search if the template above has been instantiated and will ignore this one. But in other case this template will be used and it will try to call next handler.
template<class Command, size_t handlerIndex>
std::string sendCommand(const Command& c)
{
    return sendCommand<Command, handlerIndex + 1>()(c);
}

请注意,您需要一种包含所有处理程序的注册表。在这里,我使用 std::tuple 作为这样的注册表。

关于c++ - 给定一组类,调用具有匹配方法参数的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39805508/

相关文章:

网格到网格相交的 C++ 库 : what is available?

具有友元函数和运算符重载的 C++ 模板

c++ - 我们不能从 initializer_list 创建一个 std::array,但是我们可以用一个带有可变参数的辅助函数来创建它吗?

c++ - 为什么 unique_ptr 有两个函数 reset 和 operator= 做类似的事情但不重载?

c++ - 欧拉计划 11

c++ - 为什么读取 uint8_t 为十六进制不能按预期工作?

c++ - std::map std::find 问题

c++ - 常量和非常量版本和继承

c++ - 无 ODR 使用的完美转发

c++ - shared_ptr SIGSEGV 中的无序映射