Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222

Перегрузка унарных и бинарных операторов в шаблоне

20.07.2017, 10:49. Показов 3546. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток!
Недавно столкнулся с проблемой при написании такого шаблона:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename T> class CPoint;
template <typename T> CPoint<T> operator -(const CPoint<T> &, const CPoint<T> &);
 
template <typename T>
class CPoint {
public:
    CPoint operator -() const;
    friend CPoint operator - <>(const CPoint &, const CPoint &);
};
 
template <typename T>
CPoint<T> CPoint<T>::operator -() const {
    return *this;
}
 
template <typename T>
CPoint<T> operator -(const CPoint<T> &, const CPoint<T> &) {
    return CPoint<T>();
}
При компиляции выдает кучу ошибок:
C++
1
2
3
4
5
6
7
8
9
10
11
visual studio 2017\projects\template\template\point.h(10): error C2143: синтаксическая ошибка: отсутствие ";" перед "<"
visual studio 2017\projects\template\template\point.h(11): note: см. в справочнике сведения о создании экземпляров класса класс шаблон при компиляции "CPoint<T>"
visual studio 2017\projects\template\template\point.h(10): error C2460: -: использует "CPoint<T>", определяемый в настоящий момент
visual studio 2017\projects\template\template\point.h(4): note:  см. объявление "CPoint<T>"
visual studio 2017\projects\template\template\point.h(10): error C2433: -: "friend" не разрешается для объявлений данных
visual studio 2017\projects\template\template\point.h(10): error C2473: operator -: выглядит как определение функции, но без списка параметров.
visual studio 2017\projects\template\template\point.h(10): error C2365: operator -: переопределение; предыдущим определением было "функция"
visual studio 2017\projects\template\template\point.h(4): note:  см. объявление "operator -"
visual studio 2017\projects\template\template\point.h(10): error C2238: непредвиденные лексемы перед ";"
visual studio 2017\projects\template\template\point.h(10): error C2460: -: использует "CPoint<int>", определяемый в настоящий момент
visual studio 2017\projects\template\template\main.cpp(6): note:  см. объявление "CPoint<int>"
Прицем если поменять местами унарный и бинарный минус то все нормально компилируется.
Не могу понять в чем проблема. Кто знает подскажите.
Заранее благодарен.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.07.2017, 10:49
Ответы с готовыми решениями:

В чём отличие унарных и бинарных операторов?
Подскажите пожалуйста, это унарный или бинарный оператор (а-b для комплексных чисел). Я знаю, что бинарный оператор, это когда два...

Перегрузка унарных операторов
Здравствуйте! В книге Шилдта С++ Базовый курс много примеров по перегрузке операторов. По одному из них у меня вопрос. Перегружаем...

Перегрузка унарных операторов и создание класса матриц
Пункт 1. Создать класс - координаты с унарным ++ и --, -. ++ и -- постфиксная и префиксная. - меняет знак у обеих координат. ++ как...

17
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.07.2017, 11:26
C++
1
2
3
4
5
6
//унарный минус
const ClassName operator-(const ClassName &i) 
{ return ClassName(-i.value); }
//бинарный
const ClassName operator-(const ClassName &left, const ClassName &right) 
{ return ClassName(left.value - right.value); }
Добавлено через 4 минуты
Цитата Сообщение от Demy85 Посмотреть сообщение
template <typename T>
C++
1
template<class T>
Цитата Сообщение от Demy85 Посмотреть сообщение
friend CPoint operator - <>(const CPoint &, const CPoint &);
<> - что это?
0
2393 / 1920 / 763
Регистрация: 27.07.2012
Сообщений: 5,561
20.07.2017, 11:29
Цитата Сообщение от Azazel-San Посмотреть сообщение
template <typename T>

template<class T>
Одно и то же, можно и так и так писать.
0
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222
20.07.2017, 12:20  [ТС]
Azazel-San, не работает:
C++
1
2
3
4
5
6
7
8
9
template <typename T> class CPoint;
template <typename T> const CPoint<T> operator -(const CPoint<T> &, const CPoint<T> &);
 
template <typename T>
class CPoint {
public:
    const CPoint operator -() const;
    friend const CPoint operator - <>(const CPoint &, const CPoint &);
};
Выдает то же самое.
Цитата Сообщение от Azazel-San Посмотреть сообщение
<> - что это?
Это конкретизация шаблона дружественной функции.
0
79 / 67 / 28
Регистрация: 22.04.2016
Сообщений: 384
20.07.2017, 13:22
Demy85,
Цитата Сообщение от Demy85 Посмотреть сообщение
не работает
Вам же Azazel-San совсем иначе написал.
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
3
4
5
6
//унарный минус
const ClassName operator-(const ClassName &i) 
{ return ClassName(-i.value); }
//бинарный
const ClassName operator-(const ClassName &left, const ClassName &right) 
{ return ClassName(left.value - right.value); }
1
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222
20.07.2017, 15:00  [ТС]
Цитата Сообщение от igdev Посмотреть сообщение
Вам же Azazel-San совсем иначе написал.
Да, не заметил. Так-то конечно работает и еще десятью другими вариантами, но вопрос был не как сделать по другому, а почему именно этот код не работает. Так же я обозначил что если поменять местами унарный и бинарный операторы, то проблема исчезает.

Добавлено через 8 минут

Не по теме:

- Доктор, когда я вот вот так вот делаю у меня болит..((
- А вы вот вот так вот не делайте ))))

0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
20.07.2017, 15:20
Цитата Сообщение от Demy85 Посмотреть сообщение
а почему именно этот код не работает
компилятор вам выдал перечень ошибок, гуглите..

Не по теме:

к доктору идут с мед карточкой где есть история болезни, нам же вы дали урывок кода и даже не сказали что оно должно делать



Добавлено через 1 минуту
Цитата Сообщение от Demy85 Посмотреть сообщение
- А вы вот вот так вот не делайте ))))
если не верно, то не делайте

или подождите кого-то поопытнее, я как-то так сходу не могу поправить
0
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
20.07.2017, 15:37
частичную специализацию нельзя использовать внутри шаблона класса, если не ошибаюсь
0
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222
20.07.2017, 16:01  [ТС]
Цитата Сообщение от Azazel-San Посмотреть сообщение
компилятор вам выдал перечень ошибок, гуглите..
Вы не поверите!
Цитата Сообщение от Azazel-San Посмотреть сообщение
к доктору идут с мед карточкой где есть история болезни, нам же вы дали урывок кода и даже не сказали что оно должно делать

Не по теме:

Это абстрактрый пример, задача которого воспроизводить ошибку.

Цитата Сообщение от Azazel-San Посмотреть сообщение
если не верно, то не делайте
Хотелось бы узнать что тут неверно.
Цитата Сообщение от Azazel-San Посмотреть сообщение
или подождите кого-то поопытнее, я как-то так сходу не могу поправить

Не по теме:

Так я и не тороплюсь.



Добавлено через 2 минуты
Цитата Сообщение от vndtta Посмотреть сообщение
частичную специализацию нельзя использовать внутри шаблона класса, если не ошибаюсь
А если поменять местами бинарную и унарную операцию, вот так:
C++
1
2
3
4
5
6
7
8
9
template <typename T> class CPoint;
template <typename T> CPoint<T> operator -(const CPoint<T> &, const CPoint<T> &);
 
template <typename T>
class CPoint {
public:
    friend CPoint operator - <>(const CPoint &, const CPoint &);
    CPoint operator -() const;
};
то все работает, вот в этом вся и головоломка.

Добавлено через 2 минуты
Попробовал скомпилировать с помощью MinGW - ситуация такая же.
0
93 / 69 / 22
Регистрация: 17.10.2011
Сообщений: 235
20.07.2017, 16:16
пока не объявлена дружественная функция, откуда компилятору знать, как она конкретизируется внутри шаблона? в итоге шаблон как бы не укомплектован.
а тут тип внутри шаблона выводится и никаких проблем

Добавлено через 6 минут
чесно говоря, если <> убрать из первоначального варианта, то тоже скомпилируется, другое дело, как работать будет
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
20.07.2017, 16:30
Лучший ответ Сообщение было отмечено Demy85 как решение

Решение

vndtta, не совсем то. Если сделать не оператором, а именно функцией, то получим вполне определённую ошибку "непонимания, к какой именно области видимости относится friend - функция с тем же именем". То есть для
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
template <typename T> class CPoint;
template <typename T> CPoint<T> get_something(const CPoint<T> &, const CPoint<T> &);
 
template <typename T>
class CPoint
{
    T value;
public:
    CPoint<T> &get_something(const T &);
    friend CPoint<T> get_something<T>(const CPoint<T> &, const CPoint<T> &);
};
 
template <typename T>
CPoint<T> &get_something(const T &val)
{
    value -= val;
    return *this;
}
 
template <typename T>
CPoint<T> get_something<T>(const CPoint<T> &p1, const CPoint<T> &p2)
{
    CPoint<T> differ;
    differ.value = p1.value - p2.value;
    return differ;
}
получаем
Code
1
2
3
4
error C3771: 'get_something' : friend declaration cannot be found in the nearest namespace scope
error C2143: syntax error : missing ';' before '<'
error C2460: 'get_something' : uses 'CPoint<T>', which is being defined
....
При обратном порядке компилятору становится понятно, что это тот самый шаблон функции, заголовок которой перед классом. А при таком - какую функцию выбрать на подключение - которая из класса или которая внешняя?

Добавлено через 1 минуту
Цитата Сообщение от vndtta Посмотреть сообщение
чесно говоря, если <> убрать из первоначального варианта, то тоже скомпилируется, другое дело, как работать будет
если убрать, то при попытке воспользоваться таким оператором будет ошибка линковки. Т.К. у нас объявлен именно шаблон функции, а не сама функция

Добавлено через 5 минут
Для функции это в общем-то решается вот таким объявлением:
C++
1
friend CPoint<T> (::get_something<T>)(const CPoint<T> &, const CPoint<T> &);
а вот для оператора, к сожалению, так не срабатывает почему-то.

Добавлено через 4 минуты
Хотя почему не срабатывает? Сработало :
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
template <typename T> class CPoint;
template <typename T> CPoint<T> operator-(const CPoint<T> &, const CPoint<T> &);
template <typename T> CPoint<T> operator-(const T &, const CPoint<T> &);
 
 
template <typename T>
class CPoint
{
    T value;
public:
    CPoint<T> &operator-();
    CPoint<T> &operator-(const T &);
    friend CPoint<T> (::operator-<T>)(const CPoint<T> &, const CPoint<T> &);
    friend CPoint<T> (::operator-<T>)(const T &, const CPoint<T> &);
};
 
 
template <typename T>
CPoint<T> &CPoint<T>::operator-()
{
    --value;    // !
    return *this;
}
template <typename T>
CPoint<T> &CPoint<T>::operator-(const T &decr_value)
{
    value -= decr_value;
    return *this;
}
 
template <typename T>
CPoint<T> operator-(const CPoint<T> &red, const CPoint<T> &decr)
{
    CPoint<T> differ;
    differ.value = red.value - decr.value;
    return differ;
}
template <typename T>
CPoint<T> operator-(const T &red_val, const CPoint<T> &decr)
{
    CPoint<T> differ;
    differ.value = red_val - decr.value;
    return differ;
}
 
int main()
{
   CPoint<int> point, point1;
   -point;
   point = point - 1;
   point = point - point1;
   point = 1 - point;
}
2
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222
20.07.2017, 21:37  [ТС]
Цитата Сообщение от TRam_ Посмотреть сообщение
А при таком - какую функцию выбрать на подключение - которая из класса или которая внешняя?
А не могли бы подсказать почему компилятор не может выбрать функцию, ведь сигнатуры у них разные?
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
20.07.2017, 21:52
Вероятно из-за того, что ищет строку get_something вначале в пространстве CPoint<T>:: , находит её в виде CPoint<T>::get_something, и получает конфликт с декларацией friend + не находит внешнего объявления ::get_something. А только уже потом натыкается на скобки шаблона, от того и выдаёт missing ';' before '<'
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,220
20.07.2017, 22:02
Цитата Сообщение от Demy85 Посмотреть сообщение
Не могу понять в чем проблема. Кто знает подскажите.
Проблема в том, что объявление

C++
1
friend CPoint operator - <>(const CPoint &, const CPoint &);
Должно ссылаться на предварительно объявленный шаблон operator -. Вы это знаете, ибо именно поэтому вы предварительно объявили его перед классом.

Однако вы своим объявлением унарного operator - внутри класса скрыли объявление внешнего шаблона operator -. Теперь ваше friend-объявление не видит ваше предварительное объявление, а видит только объявление унарного operator - внутри класса, которое не является шаблонным.

Если поменять местами объявление унарного operator - и friend-объявление, то сокрытие прекратится и все скомпилируется. А можно просто добавить явное указание scope во friend-объявлении

C++
1
2
3
4
5
6
7
8
9
template <typename T> class CPoint;
template <typename T> CPoint<T> operator -(const CPoint<T> &, const CPoint<T> &);
 
template <typename T>
class CPoint {
public:
    CPoint operator -() const;
    friend CPoint ::operator - <>(const CPoint &, const CPoint &);
};
1
60 / 60 / 6
Регистрация: 28.05.2012
Сообщений: 222
20.07.2017, 22:21  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вы это знаете, ибо именно поэтому вы предварительно объявили его перед классом.
От вас же и узнал из ветки Как определить дружественную функцию шаблонного класса?
Всем спасибо за помощь.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
20.07.2017, 22:37
TheCalligrapher, при
C++
1
friend CPoint ::operator - <>(const CPoint &, const CPoint &);
будет ошибка
Code
1
2
3
error: 'operator-' in 'class CPoint<T>' does not name a template type
     friend CPoint ::operator - <>(const CPoint &, const CPoint &);
                              ^
Нужно именно
C++
1
friend CPoint (::operator - <>)(const CPoint &, const CPoint &);
Добавлено через 2 минуты
И да, для такого вида нужен С++11. Иначе же нужно расписывать CPoint<T>
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,220
20.07.2017, 23:17
Цитата Сообщение от TRam_ Посмотреть сообщение
будет ошибка
Да, верно. Нужны еще скобки.

Цитата Сообщение от TRam_ Посмотреть сообщение
И да, для такого вида нужен С++11. Иначе же нужно расписывать CPoint<T>
А это почему? Внутри шаблона CPoint имя CPoint является синонимом CPoint<T> с начала времен.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
21.07.2017, 00:16
error C2955: 'CPoint' : use of class template requires template argument list
vs2010

Добавлено через 14 минут
Вот для самого класса работает:
C++
1
CPoint operator -() const;
а для friend-функции надо прописывать шаблоны явно...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.07.2017, 00:16
Помогаю со студенческими работами здесь

C++11, перегрузка бинарных операторов с r-value ссылкой
Добрый день. не так давно стал познавать азы C++11/14. Вроде во многом уже разобрался, но все покоя не дает одна вещь: почему перегружают...

Перегрузка операторов в шаблоне класса
#include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;typeinfo&gt; #include &lt;windows.h&gt; using namespace std; template &lt;class Type1,...

Перегрузка бинарных операторов для структуры в шаблонной функции
Добрый вечер уважаемые. Прошу помочь т.к. компилятор решил поставить меня в угол) Текст ошибки: 006.cpp(21): error C2804: бинарный...

Калькулятор бинарных и унарных операций
Здравствуйте. У меня есть код калькулятора, в котором я не могу правильно использовать циклы. Нужно сделать калькулятор и чтобы после...

Использование функций-членов для перегрузки унарных операторов
Добрый день уважаемые коллеги. Возник вопрос. как работают эти строки? three_d operator+(three_d op2);// оператор ор1 передается...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru