【问题标题】:Linking to dynamically available functions at compile time在编译时链接到动态可用的函数
【发布时间】:2014-10-08 17:35:39
【问题描述】:

假设我有以下核心类:

class Core {
public:
    template<typename T>
    void accept(T object);
}

我现在希望能够编写这样的方法:

void handle(int par);

并在链接/编译阶段在某处注册它们,并在Core.accept(T)方法中调用为某些类型名注册的正确方法。例如调用 Core.accept(5) 将在 5 以某种方式注册后将其交给 handle(int) 函数。像这样的东西(不可编译的例子):

template<typename T>
void Core::accept(T par) {
    // constexpr std::map<std::type_info, Function> type_func_mapping;
    auto it = type_func_mapping.get(typeid(T)); // Should be constexpr
    static_assert (it != type_func_mapping.end(), "No handler found for typename " + typeid(T).name())
    auto function = *it; // Also constexpr
    function(par);
}

这种方法有什么问题/是否存在更好的方法?

注意:我希望能够以一种可以将它们存储在只读头文件/源文件中并且甚至不必再次触摸它们的方式提取类 Core 的源代码。

【问题讨论】:

  • 为什么不能定义一个包含大量void handle(int par); void handle(double par); void handle(foo_class par); 重载的头文件?恐怕我不太明白您的要求和目标是什么。
  • 正如上面的 dyp 所说,没有理由让这个奇怪的工厂从类型映射到功能。你可以根据调用类型做函数重载,它会做你想做的一切。

标签: c++ templates c++11 compile-time


【解决方案1】:

您可以使用指向函数的指针来存储注册的函数。

static void (*reg_func)(args);
static void register(void (*func)(args)){
reg_func = func;
}

//registration part
register(handle);

//function call inside accept,use can use some sanity checks also
reg_func(5 or whatever)

有了这个,你不必接触你的核心类,甚至是包含核心类的文件。您可以在其他文件中定义句柄函数,但要注意句柄函数的可见性模式。你的句柄函数会自己注册,然后accept可以调用注册的函数。

【讨论】:

  • 这是编译时静态的吗?我怀疑。这是否适用于一次注册多个函数(因此不同的模板类型名调用不同的函数)?我看不到那个。随时给我惊喜。
  • 如果你希望它是编译时静态的,那么核心的代码就没有办法“有效地”改变。我的意思是您可以保持 Core.h 和 Core.cpp 相同,但 Core.h 必须包含一些文件,indirect.h,当您添加新类型的句柄函数时,必须对其进行修改。最后,我真正想说的是:当你添加新句柄时,如果你希望事情是编译时静态的,你将需要重新编译 Core.o……这是完全不可避免的。
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多