mas*_*tis 1 c++ templates function-pointers functor c++11
以下模板定义
template <typename Func, typename ReturnType, typename... Arguments>
class Command
{
public:
Command(Func f) : m_func(f) { }
ReturnType operator()(Arguments... funcArgs) { return m_func(funcArgs...); }
private:
Func m_func;
};
Run Code Online (Sandbox Code Playgroud)
使用以下测试代码实例化时,使用gcc 4.7.3(错误:字段'Command :: m_func'无效声明的函数类型)给出错误消息:
void testFunction(int i, double d)
{
std::cout << "TestFunctor::operator()(" << i << ", " << d << ") called." << std::endl;
}
int main()
{
void (&fRef)(int, double) = TestFunction;
Command<void(int, double), void, int, double> testCommand(fRef);
}
Run Code Online (Sandbox Code Playgroud)
如果我将没有address-of运算符的TestFunction传递给testCommand构造函数,也会出现错误消息,但如果我传递一个显式命名的函数指针或使用address-of运算符传递参数,则会消失.我认为这段代码应该适用于Modern C++ Design的第5章.
无法存储函数引用的原因是什么,但函数指针工作正常?是否有任何变通方法可以在不失去支持的情况下编译,同时也可以将函数作为参数传递给Command的构造函数?
更改一行可以修复它:
Command<void(*)(int, double), void, int, double> testCommand(fRef);
Run Code Online (Sandbox Code Playgroud)
不同的是,您现在传递的是函数指针,而不是函数类型.(函数不可复制,但指针是).
传递时,引用fRef
会衰减为函数指针.
我不建议使用std::function
性能是否重要.
在Coliru上看到它
请注意,只需稍加重写,您就可以更好地完成所有工作:
int main()
{
auto command = make_command(testFunction);
command(1, 3.14);
}
Run Code Online (Sandbox Code Playgroud)
为此,我建议将Command
模板更改为:
template <typename Func>
class Command
{
Func m_func;
public:
Command(Func f) : m_func(f) { }
template <typename... A> auto operator()(A... args) const
-> decltype(m_func(args...))
{ return m_func(args...); }
};
Run Code Online (Sandbox Code Playgroud)
现在,您可以Func
通过具有工厂函数对模板参数进行类型推导:
template <typename Func> Command<Func> make_command(Func f)
{
return Command<Func>(f);
}
Run Code Online (Sandbox Code Playgroud)
在Coliru也可以看到这种方法.当然,输出它一样:
TestFunctor::operator()(1, 3.14) called.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
703 次 |
最近记录: |