繁体   English   中英

无法从模板类调用泛型std :: function成员

[英]Cannot call generic std::function member from template class

编译以下代码时:

#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;
}

VS 2015编译器在第六行生成以下错误消息:

error C2064: term does not evaluate to a function taking 0 arguments.

现在,我相信这是因为编译器认为functionSignature不是函数签名; 例如,当我实例化并尝试在std::function<int>而不是std::function<int()>上调用operator()时,会发生同样的错误。

我怎样才能保证模板参数永远是函数签名,这样我就可以在std::function上调用operator()

我怀疑你想要这样的东西:

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...); }
};

通过使用部分特化,您可以轻松定义所需的类型。
例如,您可以将其用作:

Class<int(double)> c;

当然,我注意到你的类没有构造函数,所以调用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();
}

你的错误在这里:

 Class<void(const int)> a(std::bind(f, 10)); 

函数Class::callFunc()调用func() - 即没有参数。 std::bind(f, 10)的结果也是一个不带参数的函数,它与类模板的模板参数一致。 使用Class<void(const int)>与类模板中的用法和初始化不一致。

解决方案很简单:将错误行更改为

Class<void()> a(std::bind(f, 10));

这是你想要做的吗?

http://ideone.com/fork/IZ0Z1A

如果functionSignature不是函数,std :: function将在创建Class时抛出错误,但是你可以添加一个构造函数并抛出static_assert(std::is_function<functionSignature>::value == true," "); 如果你想我猜。

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM