Прелюдия (можно смело пропустить) Вообщем хочется написать класс полиномов над некоторым типом aType так, чтобы операции были понолстью френд-перегружены, т.е. чтобы работало int==Polynom<int>, int*Polynom<int> и другие приятности. В не-шаблонном случае это - тривиальнейшая задача. Как только я ввожу шаблоны, aType престаёт приводиться к Polynom, хотя конструктор Polynon<int> имеется. Если выкинуть контекст, и оставить только саму проблему, то получится Задача Заставить работать парой волшебных пассов Code: #include <iostream> using namespace std; template <class aType> class testClass{ public: aType data; testClass(aType c): data(c) {} bool friend operator==<aType>(testClass<aType>, testClass<aType>); }; template <class aType> bool operator==(testClass<aType> a, testClass<aType> b){ return a.data==b.data; } int main(){ int a=4; testClass<int> b(4); if (a==b) cout << "a equals b\n"; if (b==a) cout << "b equals a\n"; } В таком состоянии выдает две ошибки: Code: no match for `testClass<int> & == int &` no match for `int & == testClass<int> &` Если вызывать явные конструкторы Polynom(a)==b, всё работает, но тогда инкапсуляция и всё изящество идёт лесом. Действительно хоть какое-то решение - делать приведения явно, но внутри класса. Т.е. добавив Code: bool friend operator==<aType>(aType a, testClass b<aType>); bool friend operator==<aType>(testClass a<aType>, aType b); Ни в одной книге попавшейся мне, включая Строуструпа, этого нет. Но кажется совсем сомнительным, что это невозможно, это ж С++!!! Вообщем, надеюсь прояснить этот вопрос
Ну ясен пень, ты сравниваешь целое число и объект класса. У тебя же нет оператора их сравнения. Кстати, что за компилер? Обычно такое компилеры кушают, создавая временные объекты.. хотя хз, я точно не знаю
По-моему, просто надо реализовать соответствующий оператор копирования, поскольку по умолчанию генерируется такой оператор копирования Code: testClass<aType>& testClass<aType>::operator = (const testClass<aType>& hs) вам для неявного преобразования надо реализовать такой оператор класса, который в качестве аргумента принимает не testClass<aType>& , а аргумент aType & Code: testClass<aType>& testClass<aType>::operator = (const aType& hs){ data = hs; return *this; };
2 _Great_ У меня есть функция сравнения двух объектов класса testClass<int> и есть котструктор testClass<int>(int). Так что компилятор может привети оба операнда к типу testClass<int> и сравнить. Более того, если выкинуть все шаблоны и везде заменить aType на int (а testClass<int> b(4) на testClass b(4)), то всё именно так и работает. Компялятор - gcc (win). 2 Aag А где здесь копирование? Я же иницаализирую не элементом того же класса, а int-ом... В любом случае, добавление явного оператора копирования ничего не меняет, те же ошибки
Компильнул твой код из начала темы. Ни одной ошибки. Все работает без изменений. Получил Code: a equals b b equals a Копилятор gcc 3.3.5 (*nix) про оператор присваивания я не прав. здесь действительно инициализация идет.
Пробовал на: BSD: gcc version 3.4.2 [FreeBSD] 20040728 Linux: gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) Win: gcc version 2.95.2 19991024 (release) Win: gcc version 3.4.2 (mingw-special) И вcе выдают более-менее одну и ту же ошибку. Это однако ппц какой-то. Можете привести что точно выводит это компилятор на gcc -v ? Мож там ключи какие хитрые подефолту?
gcc -v: gcc version 3.3.5 Попробывал на mingw 3.4.5 под win действительно не работает. Но при минимальных изменениях все работает под mingw 3.4.5 Code: #include <iostream> template <typename aType> class testClass{ public: aType data; testClass(aType c): data(c) {}; bool friend operator==(testClass<aType> a, testClass<aType> b){return a.data==b.data;} ; }; int main(){ int a=4; testClass<int> b(4); if (a==b) std::cout << "a equals b\n"; if (b==a) std::cout << "b equals a\n"; }; то есть если внести описания друга внутрь класса. Вот посмотри еще http://en.wikipedia.org/wiki/Barton-Nackman_trick
2 ZaCo Ну тогда уж не operator int(), а operator aType(), но в любом случае это - не то . Этот оператор преобразует оба операнда к типу aType (в данном случае - int), и сравнивает их как инты. А если в классе не одно поле (например, рац числа над типом int), то приведение к инту даст лажу (можно приводить в частном случае к флоату, но в общем шаблонном случае непонятно к чему приводить). Убедиться, что оператор сравнения в классе testClass lдействительно не вызывается просто, достаточно добавить туда cout: Code: #include <iostream> using namespace std; template <class aType> class testClass{ public: aType data; testClass(aType c): data(c) {} bool friend operator==<aType>(testClass<aType>, testClass<aType>); operator aType(){ return data; } }; template <class aType> bool operator==(testClass<aType> a, testClass<aType> b){ cout << "Operator == exucuted\n"; return a.data==b.data; } int main(){ int a=4; testClass<int> b(4); if (a==b) cout << "a equals b\n"; if (b==a) cout << "b equals a\n"; } Этот код не выведет фразу "Operator == exucuted" ни разу