【发布时间】:2010-05-26 19:14:59
【问题描述】:
在 C# 中,我想要的是这样的:
IDictionary<string, action()> dict = new Dictionary<string, action()>();
如何在 C++ 中做到这一点?这会产生编译器错误:
map<string, void()> exercises;
【问题讨论】:
标签: c# c++ syntax functional-programming
在 C# 中,我想要的是这样的:
IDictionary<string, action()> dict = new Dictionary<string, action()>();
如何在 C++ 中做到这一点?这会产生编译器错误:
map<string, void()> exercises;
【问题讨论】:
标签: c# c++ syntax functional-programming
使用boost::function,它是一个多态包装器,可用于任何可以使用您的签名调用的对象(包括函数、函数对象等)。
map<string, function<void()>> ...;
请注意,新的 C++ 标准已将 function 包含在 <functional> 中。
解释背景:C++ 中唯一的这种内置机制是旧的 C 风格函数指针 (void (*)())。这些是非常底层的,基本上只是存储函数的内存地址,因此远未接近 C# 的委托。
您不能创建匿名函数,也不能引用特定对象的成员函数或任何变量或数据(闭包)。
因此,人们经常使用所谓的仿函数,它们是通过重载operator () 来模仿函数的行为 的类。与模板结合使用,可用于任何可以使用普通函数指针的地方。
问题是这些函子通常由不能方便引用的特殊或匿名类型组成。
function 是解决所有这些问题的最酷方法 - 一切都像函数一样,包括很酷的新 lambda 样式表达式。
function<void()> f = []() { cout << "Hello, World"> };
f();
【讨论】:
在 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 而无需输入映射...的东西。 (这也使以后更改实现变得更容易。)
【讨论】:
尝试使用函数对象。例如,您可以使用boost::function。
【讨论】: