使用模板运算符()将函数提升为任何仿函数

时间:2018-06-11 14:58:47

标签: c++ templates boost

我想存储boost::function<void(void*)>以指向任意仿函数类对象。我尝试了以下代码,但它没有编译:

struct MyFunctor
{
    template<class T>
    void operator()(T* a)
    {            
        T& ref = *a; 

    } 
};
struct MyFunctor2
{
    template<class T>
    void operator()(T* a)
    {            
        T& ref = *a; 

    } 
};

boost::function<void(void*)> anyFunctorPtr;
anyFunctorPtr= MyFunctor();
double a = 5;   
anyFunctorPtr(&a);

编译错误是错误C2182:'ref':非法使用'void'类型

1 个答案:

答案 0 :(得分:2)

boost::function,就像std::function需要特定的仿函数签名(在您的情况下为void(void*)),这是它将尝试调用您的仿函数的签名。这就是为什么T被推断为void并且编译器拒绝为您提供void&的原因。

您的示例从根本上增加了自身的赔率,因为如果您想要进行类型擦除,则不能拥有模板,因为编译器无法知道要实例化哪些模板。假设boost::function<magic>可以做你想做的事。

如果你给这样的编译器代码:

void foo(boost::function<magic> func)
{
    double a = 5;   
    func(&a);
}

编译器如何知道是否为T = doubleMyFunctor生成MyFunctor2实例化?它根本无法知道,因而无法生成正确的代码。您可以拥有的模板化仿函数类数量和可以尝试调用operator()的类型数量没有限制,因此提前自动实例化它们也是不可能的。