Больше шаблонных проблем … Я люблю 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.
Другие ответы объясняют, что происходит: когда вычитание аргумента шаблона находит два способа вывести аргумент шаблона, он рассматривает каждый из них по отдельности, и все они должны точно совпадать.
Вы, вероятно, можете заставить этот класс работать так, как вы задумывали, убедившись, что второе использование t
находится в «не выводимом контексте»:
template<typename T>
struct identity { typedef T type; };
struct blah
{
template<class t>
blah(void(*)(t), typename identity<t>::type){}
};
Таким образом, когда blah
конструктор называется, C ++ выведет t
из указателя функции, но не будет пытаться вывести его из второго аргумента. Выведенный тип затем подставляется в обоих местах.
В 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&){}
Если вы компилируете то же самое фрагмент на GCC, вы получите более интуитивное сообщение об ошибке:
test.cpp:14:20: note: deduced conflicting types for parameter ‘t’ (‘int&’ and ‘int’)
Компилятор выводит, что параметр шаблона t
является int&
для первого параметра, и int
для второго. Так как это разные типы, вы получите ошибку компиляции.