C ++ constructor error templated

More boilerplate problems ... I love C ++, but sometimes I hate it.

I can't understand 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's going on here?

I am using MSVC2008.

+6
source share
3 answers

Other answers explain what happens: when the output of the template argument finds two ways to output the template argument, it looks at each individually, and they should all agree exactly.

You can probably get this class to work the way you planned, making sure that the second use of t is in an "undetectable context":

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

Thus, when the blah constructor is called, C ++ infers t from the function pointer, but does not try to infer it from the second argument. The inferred type is then replaced in both places.

+7
source

If you compile the same snippet on gcc , you will get a more intuitive error message:

 test.cpp:14:20: note: deduced conflicting types for parameter 't' ('int&' and 'int') 

The compiler outputs that the template parameter t is int& for the first parameter, and int for the second. Since these are different types, you get a compilation error.

+3
source

In MSVC 2012, Intellisense says (roughly translated):

1 IntelliSense: no instances of the constructor "blah :: blah" "match the argument list.

Types of Arguments: (void (int &i), int)

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

You can add a second constructor

 template<class t> blah(void(*)(t), t){} template<class t> blah(void(*)(t&), t&){} 
+3
source

Source: https://habr.com/ru/post/948341/


All Articles