Ste*_*rov 6 c++ templates class function c++11
编译以下代码时:
#include <functional>
template <typename functionSignature>
class Class
{
std::function<functionSignature> func;
public:
Class(const std::function<functionSignature>& arg) : func(arg) {}
void callFunc() { func(); }
};
void f(const int i) {}
int main()
{
Class<void(const int)> a(std::bind(f, 10));
a.callFunc();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
VS 2015编译器在第六行生成以下错误消息:
error C2064: term does not evaluate to a function taking 0 arguments.
Run Code Online (Sandbox Code Playgroud)
现在,我相信这是因为编译器认为functionSignature不是函数签名; 当我实例化并尝试调用发生同样的错误operator()上std::function<int>,而不是std::function<int()>,例如.
我怎样才能保证模板参数将始终是一个函数签名,这样我可以叫operator()上std::function?
我怀疑你想要这样的东西:
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
std::function<R(P...)> func;
void callFunc(P... p) { func(p...); }
};
Run Code Online (Sandbox Code Playgroud)
通过使用部分特化,您可以轻松定义所需的类型.
例如,您可以将其用作:
Class<int(double)> c;
Run Code Online (Sandbox Code Playgroud)
当然,我注意到你的类没有构造函数,所以调用func并不是一个好主意,但是很容易定义它并传递一个适当的函数作为参数.
它遵循一个完整的工作示例,我用它operator()来调用函数:
#include <functional>
template <typename F>
class Class;
template<typename R, typename... P>
class Class<R(P...)> {
public:
Class(std::function<R(P...)> f): func{f} { }
void operator()(P... p) { func(p...); }
private:
std::function<R(P...)> func;
};
void fn() { }
int main() {
std::function<void()> f = fn;
Class<void()> c{f};
c();
}
Run Code Online (Sandbox Code Playgroud)
你的错误在这里:
Run Code Online (Sandbox Code Playgroud)Class<void(const int)> a(std::bind(f, 10));
该函数Class::callFunc()调用func()——即没有参数。的结果std::bind(f, 10)也是一个不带参数的函数,这与类模板的模板参数一致。usingClass<void(const int)>与类模板中的用法和初始化都不一致。
解决方案很简单:将错误行更改为
Class<void()> a(std::bind(f, 10));
Run Code Online (Sandbox Code Playgroud)