`std::function` 模板参数 deduction/substitution 失败

`std::function` template argument deduction/substitution failed

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

#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

问题来了: 编译器期望一些 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){}