Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ templated constructor error

More templated woes... I love C++, but sometimes I hate it.

I cannot figure out why the compiler is complaining here, and what I can do about it.

struct blah
{
   template<class t>
   blah(void(*)(t), t){}
};

void Func(int i) {}
void Func2(int& i) {}

void test()
{
   int i = 3;
   blah b(Func, i);   
   blah b2(Func2, i);        //error C2660: 'blah::blah' : function does not take 2 arguments
   blah b3(Func2, (int&)i);  //error C2660: 'blah::blah' : function does not take 2 arguments

}

What is going on here?

I am using MSVC2008.

like image 537
Tyson Jacobs Avatar asked Jun 28 '13 17:06

Tyson Jacobs


2 Answers

The other answers explain what's going on: when template argument deduction finds two ways to deduce a template argument, it looks at each alone and they all must agree exactly.

You can probably get this class working the way you intended by making sure the second use of t is in a "non-deduced context":

template<typename T>
struct identity { typedef T type; };

struct blah
{
   template<class t>
   blah(void(*)(t), typename identity<t>::type){}
};

This way when the blah constructor is called, C++ will deduce t from the function pointer, but won't try to deduce it from the second argument. The type deduced then gets substituted in both places.

like image 186
aschepler Avatar answered Oct 12 '22 12:10

aschepler


In MSVC 2012 Intellisense says (roughly transleted):

1 IntelliSense: No instances of constructor ""blah::blah"" is matching the list of arguments.

Argument types are: (void (int &i), int)

@mfontanini is correct and you have a deduction problem here.

You could add a second constructor

template<class t>
blah(void(*)(t), t){}
template<class t>
blah(void(*)(t&), t&){}
like image 27
Pixelchemist Avatar answered Oct 12 '22 13:10

Pixelchemist