Форум программистов, компьютерный форум CyberForum.ru

Шаблоны классов, перегрузка operator<< класса ostream - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.63
Konstantin_D
 Аватар для Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
18.02.2012, 18:26     Шаблоны классов, перегрузка operator<< класса ostream #1
Не компилируется программа.
fatal error: 1 unresolved externals
Как правильно определить operator<< ???

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
 
template <typename T>
class A
{
    T t;
public:
    A(T x): t(x){}
    friend ostream& operator<<(ostream& os, A& a);
};
template <typename T>
ostream& operator<<(ostream& os, A<T>& a)
{
    os << a.t;
    return os;
}
int main()
{
    A<int> a(7);
    cout << a << endl;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
18.02.2012, 18:37     Шаблоны классов, перегрузка operator<< класса ostream #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;
 
template<typename T>
class A;
 
template<typename T>
ostream& operator <<(ostream& os, const A<T>& a);
 
template <typename T>
class A
{
    T t;
public:
    A(T x): t(x) {}
    friend ostream &operator<< <T>(ostream &os, const A<T> &a);
};
template <typename T>
ostream &operator<<(ostream &os, const A<T>& a)
{
    os << a.t;
    return os;
}
int main()
{
    A<int> a(7);
    cout << a << endl;
}
Konstantin_D
 Аватар для Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
18.02.2012, 21:46  [ТС]     Шаблоны классов, перегрузка operator<< класса ostream #3
Что означает <T>(ostream &os, const A<T> &a) ?
Выглядит как приведение типа.
Как интерпретировать это <T>() ?

Код работает и без упреждающего объявления класса и функции.
Для чего нужны эти объявления?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
18.02.2012, 22:11     Шаблоны классов, перегрузка operator<< класса ostream #4
Цитата Сообщение от Konstantin_D Посмотреть сообщение
Что означает <T>(ostream &os, const A<T> &a) ?
Что функция шаблонная. В данном случае аргументы шаблона можно не писать, а оставить угловые скобки пустыми, но так не эстетично)), и я предпочитаю писать аргументы всегда. В общем случае писать надо, потому что в общем случае аргументы шаблонов не всегда могут быть выведены из параметров, переданных функции.

Цитата Сообщение от Konstantin_D Посмотреть сообщение
Код работает и без упреждающего объявления класса и функции.
Не должен...

Цитата Сообщение от Konstantin_D Посмотреть сообщение
Для чего нужны эти объявления?
Предварительное объявление функции нужно потому, что в самом классе дружественной ему объявляется конкретная инстанция этой функции (сформированная для конкретного типа). Но раз в этом месте мы говорим о конкретике, значит где-то ранее должно быть объявление общей формы (грубо, но понятно). Ну а класс, понятное дело, нужно объявить для того, чтобы затем объявить функцию, принимающую параметром ссылку на этот класс.
Konstantin_D
 Аватар для Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
19.02.2012, 16:01  [ТС]     Шаблоны классов, перегрузка operator<< класса ostream #5
Ваша подсказка натолкнула мнея на следующее:
В моем первоначальном варианте кода ошибку давал не компилятор, а компоновщик.
Причина - отсутствие необходимого инстанцирования шабона функции operator<<.
Ваше решение:

friend ostream &operator<< <T>(ostream &os, const A<T> &a);

явно указать компилятору использовать шаблон функции ( <T> ).
Это работает. Огромное спасибо.

Почему тогда НЕ работает мой первоначальный вариант с добавлением перед main()
директивы явного инстанцирования шаблона:

template ostream &operator<< <int>(ostream &os, const A<int> &a);

т.е. вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;
 
template <typename T>
class A
{
    T t;
public:
    A(T x): t(x) {}
    friend ostream &operator<< (ostream &os, const A<T> &a);
};
template <typename T>
ostream &operator<<(ostream &os, const A<T>& a)
{
    os << a.t;
    return os;
}
// Явное инстанцирование шаблона
template ostream &operator<< <int>(ostream &os, const A<int> &a);
 
int main()
{
    A<int> a(7);
    cout << a << endl;
}
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
19.02.2012, 16:37     Шаблоны классов, перегрузка operator<< класса ostream #6
Konstantin_D, да всё потому же. У вас дружественная функция не шаблонная, а фактическая реализация - шаблонная.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
using namespace std;
 
template <typename T>
class A
{
public:
    T t;
public:
    A(T x): t(x) {}
    // Не шаблон
    friend ostream &operator<< (ostream &os, const A<T> &a);
};
// Ой... Шаблон!
template <typename T>
ostream &operator<<(ostream &os, const A<T>& a)
{
    os << a.t;
    return os;
}
// Ой-ёй! Тоже шаблон!
// Явное инстанцирование шаблона
template ostream &operator<< <int>(ostream &os, const A<int> &a);
 
int main()
{
    A<int> a(7);
    cout << a << endl;
}
Таким образом, прототип дружественной функции, объявленный в классе, и функции, описанные вне класса никакой связи не имеют. Я вам показал правильный способ определения дружественной функции в шаблонном классе, по этому образцу пишется любая дружественная функция. Пользуйтесь))
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2012, 18:17     Шаблоны классов, перегрузка operator<< класса ostream
Еще ссылки по теме:

Шаблоны классов, перегрузка операторов C++
C++ Создайте класс, в котором есть ostream& operator<<. Класс должен содержать очередь с приоритетом
Friend ostream& operator<<(ostream& stream, CArr& obj); C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Konstantin_D
 Аватар для Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
19.02.2012, 18:17  [ТС]     Шаблоны классов, перегрузка operator<< класса ostream #7
Огромное С П А С И Б О !!!
Yandex
Объявления
19.02.2012, 18:17     Шаблоны классов, перегрузка operator<< класса ostream
Ответ Создать тему
Опции темы

Текущее время: 06:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru