telephone
telephone

Reputation: 1161

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

This is essentially what I am trying to do, but it fails:

#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&&’


}

The plain function will not convert into std::function, instead the compiler tries the copy or move constructor, which obviously fails. I have no idea why this happens. Is there a nice way to make line 20 working?

EDIT: Constructor of MyClass public

Upvotes: 1

Views: 1005

Answers (1)

David Haim
David Haim

Reputation: 26496

here is the problem: the compiler expects some std::function as argument in order to deduce the type T. here, you give the compiler impossible case: first implicitly convert &function into std::function<void(const int&)> then deduce T as int. the compiler doesn't know how to do it. it cant both implicitly convert pointer to funciton int std::function and deduce the template type.

second of all, the constructor is private.

now , how do we solve it?

option 1: wrap the function pointer in std::function:

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

option 2: overload the constructor as one who gets pointer to function

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

option 3: overload the constructor to some callable:

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

Upvotes: 3

Related Questions