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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.63
Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
#1

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

18.02.2012, 18:26. Просмотров 5852. Ответов 6
Метки нет (Все метки)

Не компилируется программа.
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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.02.2012, 18:26
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблоны классов, перегрузка operator<< класса ostream (C++):

Шаблоны классов, перегрузка операторов - C++
Задание:Реализовать шаблон классов Array. Перегрузить операторы присваивания =, ввода &gt;&gt; и вывода &lt;&lt; (предусмотреть обработку ошибок...

ostream &operator<< (ostream &output, const Array &obj) - что означает эта строка? - C++
void Array::getArray() // вывод массива { for (int ix = 0; ix &lt; size; ix++) cout &lt;&lt; setw(5) &lt;&lt; ptr; // вывод элементов...

friend ostream &operator<<(ostream &stream, MyClass o); - C++
Что означает данная строчка которую обычно пишут в конце класса? friend ostream &amp;operator&lt;&lt;(ostream &amp;stream, MyClass o);

Перегрузка operator* у класса Complex - C++
Complex* Complex::operator*(const Complex&amp; other) const { Complex* product = this; *product *= other; return product; }...

Перегрузка operator>> для производного класса - C++
Базовый класс: Taxi_Car.h: #pragma once #include&lt;string&gt; using namespace std; class Taxi_Car { string Marka;

Перегрузка operator<< для шаблонного класса - C++
Добрый день не могу понять как реализовать перегрузку &lt;&lt; для шаблонного класса template &lt;class T&gt; class List { public: ...

6
silent_1991
Эксперт С++
4985 / 3042 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
18.02.2012, 18:37 #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;
}
2
Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
18.02.2012, 21:46  [ТС] #3
Что означает <T>(ostream &os, const A<T> &a) ?
Выглядит как приведение типа.
Как интерпретировать это <T>() ?

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

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

Цитата Сообщение от Konstantin_D Посмотреть сообщение
Для чего нужны эти объявления?
Предварительное объявление функции нужно потому, что в самом классе дружественной ему объявляется конкретная инстанция этой функции (сформированная для конкретного типа). Но раз в этом месте мы говорим о конкретике, значит где-то ранее должно быть объявление общей формы (грубо, но понятно). Ну а класс, понятное дело, нужно объявить для того, чтобы затем объявить функцию, принимающую параметром ссылку на этот класс.
1
Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
19.02.2012, 16:01  [ТС] #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;
}
0
silent_1991
Эксперт С++
4985 / 3042 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
19.02.2012, 16:37 #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;
}
Таким образом, прототип дружественной функции, объявленный в классе, и функции, описанные вне класса никакой связи не имеют. Я вам показал правильный способ определения дружественной функции в шаблонном классе, по этому образцу пишется любая дружественная функция. Пользуйтесь))
1
Konstantin_D
14 / 14 / 2
Регистрация: 21.07.2011
Сообщений: 89
19.02.2012, 18:17  [ТС] #7
Огромное С П А С И Б О !!!
0
19.02.2012, 18:17
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2012, 18:17
Привет! Вот еще темы с ответами:

Friend ostream& operator<<(ostream& stream, CArr& obj); - C++
CArr.h #pragma once class CArr{ int* arr = nullptr; int size = 10; void swap(int *a, int *b); void swap(int &amp;a, int &amp;b); ...

Перегрузка operator< для двух экземпляров класса отрезок - C++
Всем добра, в классе отрезок хочу перегрузить операцию &lt; правильно ли я сделал ? При этом отрезок с координатами x1=1 y1=1 и x2=4 y2=4...

Перегрузить operator<<() для шаблонного класса (перегрузка оператора вывода) - C++
Здравствуйте. Перегружаю оператор вывода для шаблонного класса. using namespace std; template &lt;class Element&gt; class List { ...

Шаблоны классов: непонятная ошибка в одном из методов класса - C++
Задача создать шаблон двоичного дерева поиска. В методе удаления узла IntelliSense выдает ошибку: ссылается на if и пишет: &quot;требуется...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru