шаблоны — шаблонная ошибка конструктора c ++

Больше шаблонных проблем … Я люблю C ++, но иногда я ненавижу это.

Я не могу понять, почему компилятор жалуется здесь, и что я могу с этим поделать.

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

}

Что здесь происходит?

Я использую MSVC2008.

6

Решение

Другие ответы объясняют, что происходит: когда вычитание аргумента шаблона находит два способа вывести аргумент шаблона, он рассматривает каждый из них по отдельности, и все они должны точно совпадать.

Вы, вероятно, можете заставить этот класс работать так, как вы задумывали, убедившись, что второе использование t находится в «не выводимом контексте»:

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

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

Таким образом, когда blah конструктор называется, C ++ выведет t из указателя функции, но не будет пытаться вывести его из второго аргумента. Выведенный тип затем подставляется в обоих местах.

7

Другие решения

В MSVC 2012 Intellisense говорит (грубо переведено):

1 IntelliSense: ни один экземпляр конструктора «» blah :: blah «» не соответствует списку аргументов.

Типы аргументов: (void (int &i), int)

@mfontanini правильно, и у вас есть проблема удержания здесь.

Вы можете добавить второй конструктор

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

Если вы компилируете то же самое фрагмент на GCC, вы получите более интуитивное сообщение об ошибке:

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

Компилятор выводит, что параметр шаблона t является int& для первого параметра, и int для второго. Так как это разные типы, вы получите ошибку компиляции.

3
По вопросам рекламы [email protected]