Это потому, что другом ты объявил обычную функцию. Ее объявление найдено в классе и такая функция предпочтительнее шаблона и потому компилятор выбрал ее при разрешении перегрузки и тут-то понадобилось отсутствующее объявление
ПС А в 6ом вижуале с шаблонами-друзьями все плохо
Of course, the code must be complete enough to compile and link.
PD>Уважаемые господа!
PD>Не может ли кто-нибудь объяснить, почему этот код нормально линкуется в VC6, а в VC7.1 дает unresolved external на функцию operator<<
PD>Причем если закомментировать friend, то все линкуется нормально, но тогда, естественно, не будет доступа к полям L1, если такие добавить private.
PD>#include <iostream> PD>using namespace std; PD>template <class T> PD>class L1 PD>{ PD>public: PD> friend ostream& operator << <T>(ostream& out,L1 &A); PD>}; PD>template<class T> PD>ostream& operator << (ostream& out,L1<T> &A) PD>{ PD> return out; PD>} PD>int main() PD>{ PD> L1<int> l; PD> cout << l; PD>}
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Это потому, что другом ты объявил обычную функцию. Ее объявление найдено в классе и такая функция предпочтительнее шаблона и потому компилятор выбрал ее при разрешении перегрузки и тут-то понадобилось отсутствующее определение
L_L>ПС А в 6ом вижуале с шаблонами-друзьями все плохо
Of course, the code must be complete enough to compile and link.
Спасибо за ответ. Действительно, в 7-м Visual это компилируется. Но
1. Это не компилируется в 6-м. Как же все таки сделать в рамках того С++, что был до VC7 ?
2. Что за операция (или что такое) <> ? Никогда с ней не сталкивался. Это из стандарта C++ ? В MSDN тоже не нашел.
1. Чтобы работало с шестым, можно определять функцию друг прямо в классе (раньше так в динкумваре делали своп для вектора, например), правда, если планируешь куда-то такое переносить (на зверски стандартный компилятор), то нужно, чтоб либо функция находилась по типу аргументов АДЛем (в твоем случае это так), либо чтоб она была предварительно объявлена где-то вне класса.
2. Это не операция, это Глеб показал, что друг — специализация шаблона (тип будет выведен из параметров функции, потому скобки пустые)
Of course, the code must be complete enough to compile and link.
L_L>1. Чтобы работало с шестым, можно определять функцию друг прямо в классе (раньше так в динкумваре делали своп для вектора, например), правда, если планируешь куда-то такое переносить (на зверски стандартный компилятор), то нужно, чтоб либо функция находилась по типу аргументов АДЛем (в твоем случае это так), либо чтоб она была предварительно объявлена где-то вне класса.
Это понятно, спасибо. Работает в 7-м без этого <>.
L_L>2. Это не операция, это Глеб показал, что друг — специализация шаблона (тип будет выведен из параметров функции, потому скобки пустые)
А вот насчет этого, если можно, чуть подробнее. Когда такое в языке появилось ? Это все же из стандарта или нет ?
PD>Это понятно, спасибо. Работает в 7-м без этого <>.
Какой пример работает без <> ?
PD>А вот насчет этого, если можно, чуть подробнее. Когда такое в языке появилось ? Это все же из стандарта или нет ?
Да, из стандарта. Только конкретизируй вопрос, почему надо объявлять друга с <...> или почему могут быть пустые <> ?
Of course, the code must be complete enough to compile and link.
PD>Уважаемые господа!
PD>Не может ли кто-нибудь объяснить, почему этот код нормально линкуется в VC6, а в VC7.1 дает unresolved external на функцию operator<<
Не совсем про твой вопрос, но это тоже очень важно:
Здравствуйте, R0man, Вы писали:
R>Если можно, по-подробнее об этом операторе <>...
В принципе, выше по ветке сэр Лоренцо высказался по теме.
Кратко:
template <class T>
class A {
friend ostream& operator<<(ostream&, const A<T>&); // объявляет обычную функцию другомtemplate <class U>
friend ostream& operator<<(ostream&, const A<U>&); // объявляет шаблонную функцию другом для всех U,
// а не только для Tfriend ostream& operator<< <T>(ostream&, const A<T>&);// объявляет специализацию с аргументом T шаблонной функции
// другом - как раз то, что нужноfriend ostream& operator<< <>(ostream&, const A<T>&);// то же самое, аргумент шаблона выводится из аргументов функции
};
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, R0man, Вы писали:
R>>Если можно, по-подробнее об этом операторе <>...
A>Почему бы не читать ветку целиком для начала?
A>здесь
Ребята, я вот тут у себя в большом и древнем проекте который писали ещё наши проотцы нашел, похоже, решение этой — ну или очень похожей проблемы:
Заранее извиняюсь, если уже кто то до меня это написал. Но я не нашел, потому и хочу поделиться своим счастьем:
Итак в чем проблема: А проблема в том, что если мы хотим использовать template функцию как friend у какого-нибудь класса, то натыкаемся на проблеммы:
Проблема данного кода в том, что он не линкуется в VC6.0:
error LNK2001: unresolved external symbol "void __cdecl delete_object(class MyTest *)" (?delete_object@@YAXPAVMyTest@@@Z)
Следующие изменения не спасают в VC6.0:
class MyTest
{
~MyTest() {}
friend void delete_object<>(MyTest*);
или
friend void delete_object<MyTest>(MyTest*);
};
Compiling... error C2143: syntax error : missing ';' before '<'
Так вот как справились с этой проблемой наши проотцы:
они выкинули определение шаблонной функции в отдельный хеадер файл и его включили его туда где он необходим.
то есть: