【发布时间】:2021-11-03 22:20:23
【问题描述】:
我想知道是否有使用 C++17 标准编写类似以下代码的实用方法:
#include <string>
#include <functional>
#include <unordered_map>
template <class Arg>
struct Foo
{
using arg_type = Arg;
using fun_type = std::function< void(Arg&) >;
fun_type fun;
void call( Arg& arg ) { fun(arg); }
};
struct Bar
{
using map_type = std::unordered_map<std::string,Foo>; // that's incorrect
map_type map;
auto& operator[] ( std::string name ) { return map[name]; }
};
在上面的代码中,Foo 类的模板参数对应于某个不返回任何内容的一元函数的输入类型。具有不同模板类型的Foo 的不同实例对应于采用不同类型参数的函数。 Bar 类只是旨在为这些函数分配一个名称,但显然当前映射的声明是不正确的,因为它需要知道 Foo 的模板类型。
是吗?
【问题讨论】:
-
你想如何从地图中调用函数?如果传递了错误类型的 arg 会发生什么?
-
@HolyBlackCat 我预计会出现编译时错误,因为错误的类型被用作输入。我的预感是所有这些 Foo 实例应该具有基本相同的内存布局,并且编译器应该仍然知道参数类型是什么,因为它在类内部定义为
arg_type。但当然,这可能只是一厢情愿(或者完全错误,我实际上不知道这些类是否具有相同的布局)。 -
是什么阻止您将
fun_type设为std::any,而只将Foo::call<Arg>设为模板? -
@JonathanH 但是调用哪个函数取决于
Arg,编译器应该如何知道在给定键处调用什么函数? -
@Frank 这就是我问的原因;我不了解编译器的内部工作原理。我知道该类型实际上并未存储在内存中,但编译器通常可以很好地记住这些 typedef,而无需将它们存储在任何地方。
标签: c++ templates c++17 type-erasure