[英]Cannot call generic std::function member from template class
When compiling the following code: 编译以下代码时:
#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;
}
The VS 2015 compiler generates the following error message at the sixth line: VS 2015编译器在第六行生成以下错误消息:
error C2064: term does not evaluate to a function taking 0 arguments.
Now, I believe this is because the compiler thinks functionSignature
is not, well, a function signature; 现在,我相信这是因为编译器认为functionSignature
不是函数签名; the same error happens when I instantiate and try to call operator()
on an std::function<int>
instead of std::function<int()>
, for instance. 例如,当我实例化并尝试在std::function<int>
而不是std::function<int()>
上调用operator()
时,会发生同样的错误。
How can I guarantee that the template argument will always be a function signature, so that I can call operator()
on the std::function
? 我怎样才能保证模板参数永远是函数签名,这样我就可以在std::function
上调用operator()
?
I suspect you want something like that: 我怀疑你想要这样的东西:
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...); }
};
By using partial specialization that way you can easily define the type you want. 通过使用部分特化,您可以轻松定义所需的类型。
As an example, you can use it as: 例如,您可以将其用作:
Class<int(double)> c;
Of course, I noticed that you have no constructors for your class, so to invoke func
is not a good idea, but it's quite easy to define it and pass a proper function as an argument. 当然,我注意到你的类没有构造函数,所以调用func
不是一个好主意,但是很容易定义它并传递一个适当的函数作为参数。
It follows a complete and working example where I've used the operator()
to invoke the function: 它遵循一个完整且有效的示例,其中我使用了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();
}
Your error is here: 你的错误在这里:
Class<void(const int)> a(std::bind(f, 10));
The function Class::callFunc()
invokes func()
-- ie, no arguments. 函数Class::callFunc()
调用func()
- 即没有参数。 The result of std::bind(f, 10)
is also a function that takes no arguments, which is consistent with the template argument to the class template. std::bind(f, 10)
的结果也是一个不带参数的函数,它与类模板的模板参数一致。 Using Class<void(const int)>
is inconsistent with both the usage in the class template and the initialization. 使用Class<void(const int)>
与类模板中的用法和初始化不一致。
The solution is easy: Change the errant line to 解决方案很简单:将错误行更改为
Class<void()> a(std::bind(f, 10));
Is this what you are trying to do? 这是你想要做的吗?
http://ideone.com/fork/IZ0Z1A http://ideone.com/fork/IZ0Z1A
If functionSignature is NOT a function, std::function will throw errors when you create Class but you could add a constructor and throw there a static_assert(std::is_function<functionSignature>::value == true," ");
如果functionSignature不是函数,std :: function将在创建Class时抛出错误,但是你可以添加一个构造函数并抛出static_assert(std::is_function<functionSignature>::value == true," ");
if you want I guess. 如果你想我猜。
#include <functional>
#include <iostream>
template <typename functionSignature>
class Class
{
public:
std::function<functionSignature> func;
void callFunc() { func(); }
};
void f()
{
std::cout << "hello" << std::endl;
}
int main()
{
Class<decltype(f)> t {f};
t.callFunc();
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.