friend operator для шаблона : не генерируется в C++Builder6
От: Contact Россия http://www.lact.ru
Дата: 08.04.04 19:21
Оценка:
Я столкнулся с проблемой. Представим себе шаблонный класс; для него мы хотим завести дружественный оператор +. Проблема: если тело оператора определено внутри описания шаблона, то все ок. Если вынесено, то компилятор его (не находит?) не генерирует для конкретного типа и в результате имеем unresolved external. Проблема, видимо, актуальна только для C++ Builder 6; в других средах (под рукой оказались BorlandC++3.11(!) и MSVC6.0) все ок. Свичи билдера Jgd\Jgx не при чем.

Где же прокол?

-----------------------------
Вот исходник, на котором ставится эксперимент (консольная программа).



#include <stdio.h>

template <class T>
class Foo2
{
public:
    Foo2() {a=b=0;}
    Foo2(T c) {a=b=c;}

    Foo2& operator *= ( T c )
    {
        a *= c; b *= c;
        return *this;
    }

    friend Foo2 operator * ( T c, Foo2 p);

    T a,b;
};

template <class T>
Foo2<T> operator * ( T c, Foo2<T> p)
{
    Foo2<T> r;
    r.a = c*p.a;
    r.b = c*p.b;
    return r;
}

int main(int argc, char* argv[])
{
    Foo2<int> q(2);
    q = 2 * q;
    printf( "%d %d\n",q.a,q.b );
    return 0;
}


Спасибо за конструктивные предложения.
Павел.
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re: friend operator для шаблона : не генерируется в C++Build
От: adontz Грузия http://adontz.wordpress.com/
Дата: 08.04.04 20:17
Оценка:
Здравствуйте, Contact, Вы писали:

предложения в комментариях

#include <stdio.h>

template <class T>
class Foo2
{
public:
    Foo2() {a=b=0;}
    Foo2(T c) {a=b=c;} //Foo2(const T & c)

    Foo2& operator *= ( T c ) // Foo2& operator *= ( const T & c )
    {
        a *= c; b *= c;
        return *this;
    }

    friend Foo2 operator * ( T c, Foo2 p); // friend Foo2<T> operator * ( const T & c, Foo2<T> & p); или вообще убрать (у меня и так работает)

   T a,b;
};

template <class T>
Foo2<T> operator * ( T c, Foo2<T> p) // Foo2<T> operator * ( const T & c, Foo2<T> & p);  
{
    Foo2<T> r;
    r.a = c*p.a;
    r.b = c*p.b;
    return r;
}

int main(int argc, char* argv[])
{
    Foo2<int> q(2);
    q = 2 * q; // А где у Foo2 определён operator = ?
    printf( "%d %d\n",q.a,q.b );
    return 0;
}



Кстати unresolverd external что? какой именно специализации шаблона нахватает?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 09.04.04 02:17
Оценка:
Здравствуйте, adontz, Вы писали:

A>предложения в комментариях

Предложения учел (см.ниже), проблема не решилась...
Действительно, если просто выкинуть объявление о дружественном операторе из класса, то все будет ОК. Но хочется оставить это объявление в классе; тем более как быть, если захочется переместить члены в protected?
В общем, здесь какая-то закорючка в объявлении... Оно неправильное. Только непонятно, в чем.

A>Кстати unresolverd external что? какой именно специализации шаблона нахватает?

Специализация, собственно, одна -- Foo2<int>. Вот чего ругается компоновщик:
[Linker Error] Unresolved external 'operator *(const int&, const Foo2<int>&)' referenced from D:\WORK\GLS\VARIOUS\PATTERNS IN CPP -- FRIEND FUNX\UNI1.OBJ

Странно, правда?

Код теперь:
#include <stdio.h>

template <class T>
class Foo2
{
public:
    Foo2() {a=b=0;}
    Foo2(const T& c) {a=b=c;}

    Foo2& operator *= ( const T& c )
    {
        a *= c; b *= c;
        return *this;
    }

    Foo2& operator = ( const Foo2& p )
    {
        a = p.a; b = p.b;
        return *this;
    }


    friend Foo2 operator * ( const T& c, const Foo2& p);

    T a,b;
};

template <class T>
Foo2<T> operator * ( const T& c, const Foo2<T>& p)
{
    Foo2<T> r;
    r.a = c*p.a;
    r.b = c*p.b;
    return r;
}

int main(int argc, char* argv[])
{
    Foo2<int> q(2);
    q = 2 * q;
    printf( "%d %d\n",q.a,q.b );
    return 0;
}



Павел
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re[3]: friend operator для шаблона : не генерируется в C++Bu
От: adontz Грузия http://adontz.wordpress.com/
Дата: 09.04.04 02:46
Оценка:
Здравствуйте, Contact, Вы писали:

C>В общем, здесь какая-то закорючка в объявлении... Оно неправильное. Только непонятно, в чем.


Слушай, а если объявить этот оператор прямо в классе?


#include <stdio.h>

template <class T>
class Foo2
{
public:
    Foo2() {a=b=0;}
    Foo2(const T& c) {a=b=c;}

    Foo2& operator *= ( const T& c )
    {
        a *= c; b *= c;
        return *this;
    }

    Foo2& operator = ( const Foo2& p )
    {
        a = p.a; b = p.b;
        return *this;
    }


    friend Foo2<T> operator * ( const T& c, const Foo2<T>& p)
    {
     Foo2<T> r;
     r.a = c*p.a;
     r.b = c*p.b;
     return r;
    }

    T a,b;
};


C>Странно, правда?

Очень странно
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: friend operator для шаблона : не генерируется в C++Bu
От: WolfHound  
Дата: 09.04.04 05:47
Оценка: +1
Здравствуйте, Contact, Вы писали:

C>Странно, правда?

Вот моя версия развития событий
VC++7.1 говорит
template <class T>
class Foo2
{
public:
хъ
    friend Foo2 operator * ( const T& c, const Foo2& p);

    T a,b;
};

template <class T>
Foo2<T> operator * ( const T& c, const Foo2<T>& p)
{
    Foo2<T> r;
    r.a = c*p.a;
    r.b = c*p.b;
    return r;
}
unresolved external symbol "class Foo2<int> __cdecl operator*(int const &,class Foo2<int> const &)"

И я его понимаю. Тут ты обявляешь не шаблонный оператор, и удивляешься почему линкер его не находит.
Если написать так
Foo2<int> operator * ( const int& c, const Foo2<int>& p)
{
    Foo2<int> r;
    r.a = c*p.a;
    r.b = c*p.b;
    return r;
}

те определить оператор то все линкуется.
Или объявить в классе шаблонный оператор
    template<class U>
    friend Foo2<U> operator * ( const U& c, const Foo2<U>& p);

То тоже все линкуется.
Но для большей портабильности лучше писать
template <class T>
class Foo2
{
public:
хъ
    friend Foo2 operator * ( const T& c, const Foo2& p)
    {
        Foo2 r;
        r.a = c*p.a;
        r.b = c*p.b;
        return r;
    }

    T a,b;
};
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 09.04.04 08:26
Оценка:
Здравствуйте, WolfHound, Вы писали:

C>>Странно, правда?

WH>VC++7.1 говорит
WH>unresolved external
WH>И я его понимаю. Тут ты обявляешь не шаблонный оператор, и удивляешься почему линкер его не находит.
Хм. Я объявляю оператор не-член класса, вот и все. Ну и что что он не член? Почему то компилятор не воспринимает приводимое объявление оператора этого оператора...?
WH>Если написать так
WH>Foo2<int> operator * ( const int& c, const Foo2<int>& p)
WH>{
WH>    Foo2<int> r;
WH>    r.a = c*p.a;
WH>    r.b = c*p.b;
WH>    return r;
WH>}
>

WH>те определить оператор то все линкуется.
Да, у меня тоже все линкуется тогда отлично. Но ведь не будешь писать так для каждого аргумента шаблона...
WH>Или объявить в классе шаблонный оператор
WH>
WH>    template<class U>
WH>    friend Foo2<U> operator * ( const U& c, const Foo2<U>& p);
WH>

Но выглядит это... сами понимаете.
WH>То тоже все линкуется.
Ага, а Билдер 6 пак 4 падает [C++ Fatal Error] uni1.cpp(23): F1004 Internal compiler error at 0xc4c0ff with base 0xc10000
Вот так
WH>Но для большей портабильности лучше писать
WH>
WH>template <class T>
WH>class Foo2
WH>{
WH>public:
WH>хъ
WH>    friend Foo2 operator * ( const T& c, const Foo2& p)
WH>    {
WH>        Foo2 r;
WH>        r.a = c*p.a;
WH>        r.b = c*p.b;
WH>        return r;
WH>    }

WH>    T a,b;
WH>};
WH>


Дак нет же, так как раз писать не хочется, потому что если тела операторов на самом деле большие, а еще и проект состоит из большого числа единиц трансляции, то будет грустно.


Люди, ответ все еще не найден. Подход с
WH>
WH>    template<class U>
WH>    friend Foo2<U> operator * ( const U& c, const Foo2<U>& p);
WH>

хорош, но оставим его на крайний случай (к тому же Билдер валится).

До сих пор непонятно, почему же определение оператора не воспринимается Билдером как тело именно того оператора, что упоминается в объявлении класса?
(Кстати, в случае нешаблонного класса все отлично!).

Буду продолжать возиться и бороться и ждать предложений,

Павел.
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re: friend operator для шаблона : не генерируется в C++Build
От: Lorenzo_LAMAS  
Дата: 09.04.04 11:08
Оценка:
Билдер в данном случае — прав.
template<class T>
class A
{
   friend void fun(T);
};

template<class T>
void fun(T)
{
}


Хочу порадовать, другом ты объявил НЕ шаблон функции, а соответствующую функцию. Т.е., допустим, void fun(int) будет другом для A<int> и т.д.
Чтоб получить то, что ты хочешь, надо писать так

template<class T>
class A
{
public:
   template<class T>friend void fun(T);
};


Просьба, не писать VC6.0 cчитает по другому и т.д. — он друзей шаблонов не поддерживает(да и 7.0 тоже плох по этой части).
Of course, the code must be complete enough to compile and link.
Re[2]: friend operator для шаблона : не генерируется в C++Bu
От: Lorenzo_LAMAS  
Дата: 09.04.04 11:15
Оценка:
Поправки
L_L>
L_L>   template<class T1>friend void fun(T1);
L_L>
Of course, the code must be complete enough to compile and link.
Re[5]: friend operator для шаблона : не генерируется в C++Bu
От: Lorenzo_LAMAS  
Дата: 09.04.04 11:26
Оценка:
Оставшийся вариант это именно вариант с определением в теле класса, он как раз описывается, допустим, у Джосутисса/Вандевурда как способ борьбы с дрянными компиляторами.

Если у тебя есть iso/iec 14882 — почитай про друзей шаблонов, там объясняется что:
template<class T>
class A
{
   friend void fun(T);//здесь другом объявлена ОБЫЧНАЯ функция, а не шаблон
   template<class T1>
   friend void fun(T1);//здесь то, что ты хотел.
}


Попробуй еще так

template<class T>
class A;

template<class T>
void fun(A<T>);

template<class T>
class A
{
public:
    friend void fun<T>(A<T>);
private:
    int i_;
};

template<class T>
void fun(A<T> a)
{
   a.i_ = 0;
}

int main()
{
    A<int>a;
    fun(a);

    return 0;
}
Of course, the code must be complete enough to compile and link.
Re[3]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 09.04.04 16:28
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Поправки

L_L>>
L_L>>   template<class T1>friend void fun(T1);
L_L>>

Эх, вот то то и оно. Конструкция template <class T> для функции работает отлично; а вот для оператора...

Всего сейчас рассмотрено три возможных подхода для объявления:

1. friend Foo2<T> operator * ( T const & c, Foo2<T> const & p); //(По поводу этого будет вопрос...(ниже)).

2. template <class T> friend Foo2<T> operator * ( T const & c, Foo2<T> const & p);

3. template <class T1> friend Foo2<T1> operator * ( T1 const & c, Foo2<T1> const & p);

Можно даже составлять таблицу попыток сборки примера;(


Такие пока дела...
Самое обидное, что модуль, с которым я парюсь, планировался как основа кросплатформенного/(и сверхнезависимого-от-среды-программирования) ядра одной штуки...))

p.s.
С шаблоном оператора я примерно понял, почему так. Хотя, не до конца. Можно маленький ликбез?
template <class T> friend fun(Foo2<T>);

-- ссылка в объявлении на friend-функцию, которая шаблон? Так?

friend fun(Foo2<T>);

-- ссылка на friend-функцию, которая просто функция. Так?

А как правильно трактовать ситуацию, когда я потом пишу шаблон этой функции:
template <class T>
fun (Foo2<T> a)
{
...
}

Это определение будет распознаваться как то-самое, на которое мы ссылаемся по
а) Первому методу (ну, это очевидно)
б) Второму? (вот в чем вопрос)


Буду очень благодарен,
Павел.
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re[4]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 09.04.04 17:14
Оценка:
Вопрос секции p.s. снимается. (см. объяснение http://www.rsdn.ru/Forum/Message.aspx?mid=600963&amp;only=1
Автор: Lorenzo_LAMAS
Дата: 09.04.04
)
Печальность ситуации, тем не менее, не снимается.
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re[4]: friend operator для шаблона : не генерируется в C++Bu
От: folk Россия  
Дата: 10.04.04 02:11
Оценка:
Здравствуйте, Contact, Вы писали:

C>Всего сейчас рассмотрено три возможных подхода для объявления:


C>
C>1. friend Foo2<T> operator * ( T const & c, Foo2<T> const & p); //(По поводу этого будет вопрос...(ниже)).
C>

C>
C>2. template <class T> friend Foo2<T> operator * ( T const & c, Foo2<T> const & p);
C>

C>
C>3. template <class T1> friend Foo2<T1> operator * ( T1 const & c, Foo2<T1> const & p);
C>

C>Можно даже составлять таблицу попыток сборки примера;(

C>Подход 1:

C>b6: unresolved external
C>vc6: ok
C>vc7: unresolved external

C>Подход 2:

C>b6: internal compiler error
C>vc6: error C2908: explicit specialization во время определения тела оператора
C>vc7: все ок. Временами internal compiler error (недописать в объявлении где-нибудь <T> )

Имхо здесь и должна быть ошибка, vc6 показал себя с лучшей стороны

C>Подход 3:

C>То же что и 2, только vc7 ведет себя постабильнее.

C>Такие пока дела...

C>Самое обидное, что модуль, с которым я парюсь, планировался как основа кросплатформенного/(и сверхнезависимого-от-среды-программирования) ядра одной штуки...))

По-моему происходит топтание на месте. Если твои компиляторы не согласны с шаблонными операторами-друзьями, то:

1. Либо определи нешаблонного оператора-друга прямо в определении класса, как сначала и предлагали.

2. Либо вообще избавься от таких друзей. Обычно оператор * можно выразить в терминах открытых функций-членов — конструктора копирования и оператора *= :

template <class T>
class Foo2
{
public:
    Foo2& operator *= (T c);
    //...
};

template <class T>
Foo2<T> operator * (T c, Foo2<T> p)
{
    Foo2<T> r(p);
    return r *= c;
}
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[5]: friend operator для шаблона : не генерируется в C++Bu
От: Lorenzo_LAMAS  
Дата: 10.04.04 08:14
Оценка:
Почему-то он проигнорировал такое предложение

template<class>
class A;
template<class T>
A<T> operator + (const A<T> &, const A<T>&);

template<class T>
class A
{
   friend A operator+<T>(const A<T>&, const A<T> &);
};

template<class T>
A<T> operator + (const A<T> &, const A<T> &)
{
////
}


Что, с одной стороны, правильно, с другой стороны им еще не опробовано
Of course, the code must be complete enough to compile and link.
Re[4]: friend operator для шаблона : не генерируется в C++Bu
От: Lorenzo_LAMAS  
Дата: 10.04.04 08:22
Оценка:
Ты однако не счел нужным заметить показанный мною ЧЕТВЕРТЫЙ способ. БЦЦ у меня нет, проверить не смогу. Дело за тобой.

template<class>class A;
template<class T>
A<T> operator + (const A<T> &, const A<T> &);

template<class T>
class A
{
   friend operator +<T>(const A&, const A &);
};



Здесь другом объявлена специализация шаблонной функции

C>p.s.

C>С шаблоном оператора я примерно понял, почему так. Хотя, не до конца. Можно маленький ликбез?
C>template <class T> friend fun(Foo2<T>);

C>-- ссылка в объявлении на friend-функцию, которая шаблон? Так?

Да, об этом раза 4 сказали уже.

C>
C>friend fun(Foo2<T>);
C>

C>-- ссылка на friend-функцию, которая просто функция. Так?

Да.

C>А как правильно трактовать ситуацию, когда я потом пишу шаблон этой функции:

C>
C>template <class T>
C>fun (Foo2<T> a)
C>{
C>...
C>}
C>

C>Это определение будет распознаваться как то-самое, на которое мы ссылаемся по
C>а) Первому методу (ну, это очевидно)
C>б) Второму? (вот в чем вопрос)

Какой вопрос? Это же шаблон функции, а во втором случае другом объявлена нешаблонная функция.
Of course, the code must be complete enough to compile and link.
Re[5]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 10.04.04 23:43
Оценка:
L_L>Ты однако не счел нужным заметить показанный мною ЧЕТВЕРТЫЙ способ. БЦЦ у меня нет, проверить не смогу. Дело за тобой.

Эх, да. Я, извиняюсь, отмел его как синтаксическую ошибку постинга, ибо vc6sp5 поругался на синтаксическую ошибку
template<class T>
class A
{
   friend operator +<T>(const A&, const A &);
                    ^
};


Сейчас перепроверил в bc6 и vc7-2002, они съели.
thnx.

Зато vc6 ест обычный вариант.
Нда, пока получается, что без сишных макросов аля
#if bcc|vc7
#define _T <T>
#else
#define _T 
#endif
....
friend operator + _T(const A&, const A &);

не обойтись
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re[6]: friend operator для шаблона : не генерируется в C++Bu
От: discretus Россия  
Дата: 11.04.04 14:03
Оценка:
Здравствуйте, Contact, Вы писали:

L_L>>Ты однако не счел нужным заметить показанный мною ЧЕТВЕРТЫЙ способ. БЦЦ у меня нет, проверить не смогу. Дело за тобой.


C>Эх, да. Я, извиняюсь, отмел его как синтаксическую ошибку постинга, ибо vc6sp5 поругался на синтаксическую ошибку

C>
C>template<class T>
C>class A
C>{
C>   friend operator +<T>(const A&, const A &);
C>                    ^
C>};
C>


C>Сейчас перепроверил в bc6 и vc7-2002, они съели.

C>thnx.

C>Зато vc6 ест обычный вариант.

C>Нда, пока получается, что без сишных макросов аля
C>
C>#if bcc|vc7
C>#define _T <T>
C>#else
C>#define _T 
C>#endif
C>....
C>friend operator + _T(const A&, const A &);
C>

C>не обойтись

Слушайте ребят, возможно у меня есть решение этой проблемы....
Дело в том, что шаблоны, в отличие от классов, создаются лишь при конструировании конкретных классов из шаблона, поэтому, чтобы не было ошибки "unresolved external и т.д." нужно сделать следующее:

Пояснение:
1. Эта ошибка не связана с "friend"
2. Скорее всего рассматриваемые шаблоны разнесены на два файла (.h и .cpp), верно?
3. Если да, то скорее всего вы прописываете #include "file.h" в начале .cpp?
4. Путь решения: в конце хедера прописать #include "file.сpp", а в начале .cpp убрать #include "file.h"
5. В основной программе продолжать использовать #include "file.h".

Должно заработать! У меня когда-то тоже была такая проблема, мучался довольно долго. Удачи
Re[7]: friend operator для шаблона : не генерируется в C++Bu
От: discretus Россия  
Дата: 11.04.04 22:06
Оценка:
Кое что я написал неверно: уточнение: в пункте 3: в начале .cpp убирать #include "file.h" не нужно, однако нужно заключисть при этом весь файл .cpp в скобки

#ifndef fileCPP
#define fileCPP

...

#endif

Удачи!
Re[8]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 12.04.04 00:47
Оценка:
Здравствуйте, discretus!

Да, подход к шаблонам абсолютно правильный и иначе с ними ничего не поделаешь --
1) надо либо все определять в единице трансляции (как ты предлагаешь) (ибо слово export почти нигде не работает и девелоперы компиляторов его ругают)
2) либо извращаться по особому и заставлять инстанциировать конкретные, нужные нам специализации в специально отведенных для этого единицах

D>Удачи!

спасибо!
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
Re[6]: friend operator для шаблона : не генерируется в C++Bu
От: Lorenzo_LAMAS  
Дата: 12.04.04 06:19
Оценка:
C>Эх, да. Я, извиняюсь, отмел его как синтаксическую ошибку постинга, ибо vc6sp5 поругался на синтаксическую ошибку

VC 6 не понимает шаблонов друзей. Единственная доступная возможность правильно работать с шаблонами и друзьями в нем — это определять функцию друг в шаблонном классе, т.е. делать ее встроенной. Это решение, с другой стороны, может вызвать свои проблемы, типа множественного определения функции:

template<class T>
class A
{
public:
    friend void fun(){}
};

A<int>a;
A<double>b;



Или, что то же не есть хорошо: для строгих компиляторов в случае если функция не имеет параметров типа класса (причем необязательно класса шаблона), который ее другом объявил, и ты не объявишь ее вне класса, то тогда имя этой функции не будет видно. Правда, это так только для строгих компиляторов, VC, BCC всегда плевали на это. Пример строгого компилятора:

template<class>
class A
{
   friend void fun(){}
};

void g()
{
   fun();
}


Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATION_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++

"ComeauTest.c", line 9: error: identifier "fun" is undefined
fun();
^

1 error detected in the compilation of "ComeauTest.c".

In strict mode, with -tused, Compile failed



C>Сейчас перепроверил в bc6 и vc7-2002, они съели.

C>thnx.

Что такое bc6 ? CBuilder 6.0 & bcc 5.6 ?
vc 7.0 странный, он поддерживает друзей шаблонов только частично, допустим, этот вариант пропер, а другие нет либо работают неправильно.
Of course, the code must be complete enough to compile and link.
Re[7]: friend operator для шаблона : не генерируется в C++Bu
От: Contact Россия http://www.lact.ru
Дата: 13.04.04 01:55
Оценка:
L_L>VC 6 не понимает шаблонов друзей.
Странно... Ну да бог с ним, ведь удалось получить от него то, что хотелось (см. p.s.)

L_L>Или, что то же не есть хорошо: для строгих компиляторов в случае если функция не имеет параметров типа класса (причем необязательно класса шаблона), который ее другом объявил, и ты не объявишь ее вне класса, то тогда имя этой функции не будет видно. Правда, это так только для строгих компиляторов, VC, BCC всегда плевали на это.

Да уж. Надеюсь, стандарт по этому поводу пофиксят. Строгость -- это конечно хорошо, но уж пусть она будет еще и краткой. А пока будем писать дважды: "есть такая функция, вот ее аргументы, знай;.. есть такая функция, вот с такими аргументами, так вот знай, она -- друг."

L_L>Что такое bc6 ? CBuilder 6.0 & bcc 5.6 ?

ну да, я имел ввиду bcc 5.6.2 (последнего из магикан )
L_L>vc 7.0 странный, он поддерживает друзей шаблонов только частично, допустим, этот вариант пропер, а другие нет либо работают неправильно.
Про их поддержку Стандарта: в msdn, например, нашлась целая статься по поводу того, как vc7- 2003 неправильно понимает этот самый стандарт по части шаблонов.

p.s.
Здесь видимо я намешал всего; но это работает и для bcc, и для ms6-7-02/03. Не знаю, что уж они там себе думают, но мы получаем результат на всех.

//+++++++++++++++ foo.h
template <class T> class Foo2; //так надо для следующего объявления
template <class T> Foo2<T> operator * ( T c, Foo2<T> p); //объявим, что есть такой оператор -- *

// компилятор BorlandC захочет <T>, когда будем упоминать друга-оператора
// а компилятор msvc6 будет плакать, когда увидит там <T>. Используем макросы.
#define _T
#if defined(__BORLANDC__) || defined(__SOMEONELIKEBORLANDC__)
#undef  _T
#define _T  <T>
#endif 

template <class T>
class Foo2
{
public:
    Foo2();
    Foo2(T);
    Foo2 fun( T ); 

    //friend Foo2 operator * ( T c, Foo2 p);   -- так надо для vc
    //friend Foo2 operator * <T>( T c, Foo2 p); -- так надо для билдера
    friend Foo2 operator * _T( T c, Foo2 p); // -- мы пойдем таким путем (через макросы)
protected:
    T a,b;
};
 

template <class T>
Foo2<T> operator * ( T c, Foo2<T> p)
{
    Foo2<T> r;
    r.a = c*p.a;
    r.b = c*p.b;

    return r;
}

//+++++++++++++++ вот и все
С уважением,
Павел Васёв
-------------
LineAct &mdash; автоматическое создание Вашего сайта под ключ: дизайн, хостинг, online cms, хранилище файлов &mdash; стоит всего 6000 р...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.