在C#中,我想要的东西会是这样的:
IDictionary<string, action()> dict = new Dictionary<string, action()>();
如何在C ++中执行此操作?这会给编译器错误:
map<string, void()> exercises;
答案 0 :(得分:6)
使用boost::function,一个多边形包装器,用于任何可以使用签名调用的对象(包括函数,函数对象等)。
map<string, function<void()>> ...;
请注意,新的C ++标准已在function
中包含<functional>
。
解释背景:C ++中唯一的这种内置机制是旧的C风格函数指针(void (*)()
)。这些都是极低级别的,基本上只是存储一个函数的内存地址,因此甚至远不能接近C#代表的权力。
您不能创建匿名函数,也不能引用特定对象的成员函数或任何变量或数据(闭包)。
因此,人们经常使用所谓的仿函数,它们是通过重载operator ()
来模仿函数的行为的类。与模板结合使用时,可以使用普通函数指针。
问题在于这些仿函数通常由特殊或匿名类型组成,无法方便地引用。
function
是解决所有问题的最酷方式 - 所有行为都像一个函数,包括很酷的新lambda样式表达式。
function<void()> f = []() { cout << "Hello, World"> };
f();
答案 1 :(得分:3)
在C ++函数中需要使用指针。使用C ++示例,您可以将其内联为:
map<string, void(*)()> exercises;
但对于不经意的观察者来说,分两行来说可能更有用:
typedef void (*pointer_to_void_function)();
map<string, pointer_to_void_function> exercises;
(选择适合的名字。)
请注意,偶然的观察者可能更容易添加另一个typedef ...
typedef void (*pointer_to_void_function)();
typedef map<string, pointer_to_void_function> ExerciseMapping;
ExerciseMapping exercises;
然后,当你想使用迭代器或其他什么时,你只需输入ExerciseMapping::iterator
而不是需要输入map ...东西。 (这也使得以后更容易更改您的实现。)
答案 2 :(得分:0)
尝试使用功能对象。例如,您可以使用boost::function。