`std :: function`模板参数推导/替换失败

时间:2015-07-12 10:43:59

标签: templates c++11 implicit-conversion

这基本上就是我想要做的,但它失败了:

#include <functional>


class MyClass
{
public:
    template <typename T>
    MyClass(const std::function<void (const T& )>& )
    {
    }

};

void function(const int& i)
{

}

int main()
{
    MyClass t( &function );
    // ^ main.cpp: In function ‘int main()’:
    //   main.cpp:20:26: error: no matching function for call to
    //   ‘MyClass::MyClass(void (*)(const int&))’
    //        MyClass t( &function );
    //                             ^
    //   main.cpp:7:5: note: candidate: 
    //   template<class T> MyClass::MyClass(const std::function<void(const T&)>&)
    //        MyClass(const std::function<void (const T& )>& )
    //        ^
    //   main.cpp:7:5: note:   template argument deduction/substitution failed:
    //   main.cpp:20:26: note:   mismatched types 
    //   ‘const std::function<void(const T&)>’ and ‘void (*)(const int&)’
    //        MyClass t( &function );
    //                             ^
    //   main.cpp:4:7: note: candidate: constexpr MyClass::MyClass(const MyClass&)
    //    class MyClass
    //          ^
    //   main.cpp:4:7: note:   no known conversion for argument 1 from 
    //   ‘void (*)(const int&)’ to ‘const MyClass&’
    //   main.cpp:4:7: note: candidate: constexpr MyClass::MyClass(MyClass&&)
    //   main.cpp:4:7: note:   no known conversion for argument 1 from 
    //   ‘void (*)(const int&)’ to ‘MyClass&&’


}

普通函数不会转换为std::function,而是编译器尝试复制或移动构造函数,这显然会失败。我不知道为什么会这样。是否有一种很好的方法让20号线工作?

编辑: MyClass的构造函数public

1 个答案:

答案 0 :(得分:2)

这是问题所在: 编译器期望一些std::function作为参数,以推导出类型T。在这里,您为编译器提供了不可能的案例:首先将&function隐式转换为std::function<void(const int&)>,然后将T推导为int。编译器不知道该怎么做。它不能隐式地将指针转换为funciton int std :: function并推导出模板类型。

第二,构造函数是私有的。

现在,我们如何解决它?

选项1: 将函数指针包装在std :: function中:

MyClass t( std::function<void(const int&)>(function) );

选项2: 将构造函数重载为获取函数指针的人

template <class T> 
    MyClass(void (*p)(const T& ))
    {
    }

选项3: 将构造函数重载为某些可调用的:

template <class Callable>
Myclass (Callable c){}