Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
8 / 7 / 1
Регистрация: 13.06.2017
Сообщений: 56

Перегрузка оператора у вложенного класса шаблона

25.04.2020, 01:06. Показов 2944. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я объявляю шаблонный класс A и хочу иметь в нем вложенный класс B, к которому будет применим бинарный плюс следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
class A
{
public:
    class B;
};
 
template <typename T>
class A<T>::B
{
 
};
 
template <typename T>
typename A<T>::B operator+(int n, typename A<T>::B b)
{
    return A<T>::B();
}
 
void main()
{
    1 + A<int>::B();
}
Когда я неявно вызываю +, соответствующая функция не находится.

Какой должна быть сигнатура перегрузки чтобы это заработало?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.04.2020, 01:06
Ответы с готовыми решениями:

Перегрузка оператора- для шаблона класса
Ребят подскажите что не так я делаю или подтолкните в нужное русло =\ З.Ы. Массивы будем рассматривать одинаковой длины. #include...

Перегрузка оператора << для шаблона
У меня есть структура студенты, а класс-шаблон массив элементов. Как сделать оператор универсальным, подходящим для любых типов(и для...

Перегрузка оператора >> для дочернего класса от базового виртуального класса
Доброго вам времени суток! Программирую на С++ не давно, в связи с отсутствием должного времени на поиск ответа в глубинах учебников,...

22
Гвоздь Задиров
 Аватар для Folian
1719 / 1118 / 337
Регистрация: 25.01.2019
Сообщений: 2,946
25.04.2020, 01:19
Цитата Сообщение от Zegors Посмотреть сообщение
чтобы это заработало?
а что ты вообще пытаешься сделать?
0
8 / 7 / 1
Регистрация: 13.06.2017
Сообщений: 56
25.04.2020, 01:23  [ТС]
В контексте данного примера я пытаюсь вызвать перегрузку + у int и A<int>::B, изначально у меня был шаблонный класс контейнер к которому нужно было сделать итератор с арифметикой, я упростил до такого состояния.

Если явно вызывать оператор то это работает:
C++
1
    operator+<int>(1, A<int>::B());
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
25.04.2020, 01:46
Zegors,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename T>
class A
{
public:
    class B;
};
 
template <typename T>
class A<T>::B
{
     friend B operator+(int n, B b)
     {
         return B();
     }
};
 
int main()
{
    1 + A<int>::B();
}
2
8 / 7 / 1
Регистрация: 13.06.2017
Сообщений: 56
25.04.2020, 01:51  [ТС]
ablex, Мне бы не хотелось во первых нарушать инкапсуляцию, во вторых хотелось бы отделять объявление от определения, т. е. объявлять за пределами класса, такая сигнатура единственно возможная?
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
25.04.2020, 02:03
Лучший ответ Сообщение было отмечено Zegors как решение

Решение

Цитата Сообщение от Zegors Посмотреть сообщение
не хотелось во первых нарушать инкапсуляцию
friend не нарушает инкапсуляцию. Это альтернативный способ описания интерфейса класса. Вы же не будете утверждать, что объявление функции-члена нарушает инкапсуляцию? Не подменяйте понятия.

Цитата Сообщение от Zegors Посмотреть сообщение
такая сигнатура единственно возможная?
Это наиболее простой вариант обеспечить работоспособность.
Прежде чем рассуждать дальше, предлгаю все-таки сперва разобраться, почему ваш вариант не работоспособен.
https://stackoverflow.com/a/25245676

Если останутся вопросы по материалу по ссылке, задавайте их тут.
2
8 / 7 / 1
Регистрация: 13.06.2017
Сообщений: 56
25.04.2020, 02:25  [ТС]
ablex, Спасибо, я и подумать не мог что нельзя вывести тип из такой очевидной ситуации)
Цитата Сообщение от ablex Посмотреть сообщение
friend не нарушает инкапсуляцию
Практически это остается на совести программиста, а не контролируется компилятором, поэтому с точки зрения кодстайла объявлять много friend наверное все таки плохо.
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
25.04.2020, 02:28
Цитата Сообщение от Zegors Посмотреть сообщение
я и подумать не мог что нельзя вывести тип из такой очевидной ситуации)
У меня подозрения, что вы не совсем поняли материал по ссылке, раз все еще считаете эту ситуацию очевидной.
0
8 / 7 / 1
Регистрация: 13.06.2017
Сообщений: 56
25.04.2020, 02:32  [ТС]
ablex, "казалось бы очевидной ситуации"
0
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
25.04.2020, 03:19
Цитата Сообщение от Zegors Посмотреть сообщение
поэтому с точки зрения кодстайла объявлять много friend наверное все таки плохо.
В вашей ситуации не понятно, уместно ли вообще использование такого вложенного класса внутри шаблона, если вы предполагаете его внешнее использование. Иными словами, раз вы уверены, что friend раскроет слишком много деталей реализации класса B для оператора+, то нужно воспринимать это как маркер для сомнений в верности изначальной постановки о вложенности B в шаблон.

Но до тех пор, пока мы разговариваем в абстрактных B - A что-то осмысленное предложить невозможно. Но можете считать, что лакмусовая бумажка сработала. Думайте в сторону изменения архитектуры.

Цитата Сообщение от ablex Посмотреть сообщение
считаете эту ситуацию очевидной.
Вы своим примером как бы говорите: выведи мне T из контекста, который зависит от T. Поясняю. B - зависимое имя шаблона, т.е. это B - зависит от T, но вы хотите чтобы T вывелось из B. Причинно-следственные связи нарушены. Логика не работает. Конкретно компилятор и C++ глобально здесь и не при чем, скорее законы природы.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,226
25.04.2020, 04:50
Цитата Сообщение от Zegors Посмотреть сообщение
такая сигнатура единственно возможная?
Да, в варианте предложенном ablex, оператор сам по себе не является шаблонной функцией, а является, условно выражаясь, автоматически генерируемой нешаблонной функцией (как ни странно это звучит). Именно поэтому его вариант не страдает от проблем с non-deduced context, ибо такой функции не нужна дедукция шаблонных аргументов вообще.

К сожалению язык С++ не предоставляет других способов определения таких функций. Только как friend, и только с определением прямо в теле класса.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.04.2020, 10:37
Zegors, я вот тоже не понимаю, почему литерал 1 не воспринимается как тип int... Однако, если задать тип первого слагаемого как шаблонный параметр то вывод проходит успешно:
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
#include <iostream>
 
template <typename T>
class A
{
public:
    class B;
};
 
template <typename T>
class A<T>::B
{
 
};
 
template <typename T>
typename A<T>::B operator+(T n, typename A<T>::B b)
{
    return typename A<T>::B();
}
 
int main()
{
    1+A<int>::B();
    return 0;
}
Это странно. Неоднозначности нет, но компилятор упорно не принимает конкретный тип в данном случае. А вот по шаблонному параметру (где труднее вывести - так как чуть больше работы), он выводит без проблем.
Это для MinGW)
Утверждения вроде того, что де такова судьба, исходя из того, что на то воля божья, не успокаивают.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,226
25.04.2020, 11:34
Цитата Сообщение от IGPIGP Посмотреть сообщение
я вот тоже не понимаю, почему литерал 1 не воспринимается как тип int...
Почему вы решили, что "литерал 1 не воспринимается как тип int"? И какое это вообще имеет отношение к данному примеру?

Цитата Сообщение от IGPIGP Посмотреть сообщение
Однако, если задать тип первого слагаемого как шаблонный параметр то вывод проходит успешно
Что логично и понятно. Теперь компилятор может очевидным и элементарным образом выполнить дедукцию шаблонного аргумента для T через первый аргумент функции, именно пользуясь вашим же "литерал 1 воспринимается как тип int".

Цитата Сообщение от IGPIGP Посмотреть сообщение
Это странно.
???
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.04.2020, 11:51
Посмотрел вопрос по ссылке на stack overflow и не увидел убедительных объяснений. Я дополнил его вызовом с "подсказкой" - явным инстанцированием. Этот вызов работает.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <map>
 
template<typename T>
struct TMap
{
    typedef std::map<T, T> Type;
};
 
 TMap<double>::Type tmap1;
 
template<typename T>
T test(typename TMap <T>::Type &tmap_) { return 0.0; }
 
int main(int argc, char* argv[])
{
    TMap<double>::Type tmap;
    tmap[1.1] = 5.2;
   //double d = test(tmap); //Error: could not deduce template argument for T
   double d = test<double>(tmap);//ok
    return 0;
}
Мне нравится фраза Питтера Готшлинга о чём-то схожем. Он ссылается на авторитет для большей устойчивости, но некоторый юмор можно уловить (или мне показалось?). Он говорит, о том, что и С. Мейерс не советует перегружать шаблонные методы, а считает лучшим вариантом обычную перегрузку. А дальше - причина: это потому, что к сожалению перегруженные шаблонные методы иногда не вызываются.
Пишу по памяти - не взыщите. Однако там вопрос шире, в том смысле, что может вызываться построение менее подходящего инстанса.

*Тут попутно, снова есть какой-то раздосадованный шум. Я обещал, что не буду реагировать на бессмысленные с недоуменно грубым оттенком выбросы и я не буду.
0
25.04.2020, 12:12

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
*Тут попутно, снова есть какой-то раздосадованный шум. Я обещал, что не буду реагировать на бессмысленные с недоуменно грубым оттенком выбросы и я не буду.
Вашей реакции и не требуется. Как уже не раз объяснялось, целью данного "шума" является лишь повесить на ваши излияния табличку для начинающих: "Внимание! Написана чушь. Не обращайте внимания"

0
25.04.2020, 12:18

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вашей реакции и не требуется. Как уже не раз объяснялось, целью данного "шума" является лишь повесить на ваши излияния табличку для начинающих: "Внимание! Написана чушь. Не обращайте внимания"
TheCalligrapher, вы юлите так будто и русский язык не понимаете. Это обращение ко мне лично:
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Почему вы решили
и ваши попытки выдать это за явный тип подлости не ясны. Вешать таблички без аргументов, но грубо - признак тяжелого жлобства. Поэтому, впредь - прошу писать прямо. Как на табличке. Объяснять не буду но - чушь! Что бы было виднее, кто и что пишет.
Я к вашим выбросам уже привык.

0
25.04.2020, 12:20

Не по теме:

IGPIGP,

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<class T> struct bar
{
    using type = int;
};
 
template<class T> void foo(typename bar<T>::type)
{
}
 
int main()
{
    bar<double>::type val1 = 5;
    int val2 = 3;
    foo(val1); // чем это
    foo(val2); // отличается от этого? И какой тип T должен быть выведен тут?
}

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,226
25.04.2020, 12:31

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
TheCalligrapher, вы юлите так буд-то и русский язык не понимаете. Это обращение ко мне лично:
Вы, очевидно, проглядели вводные слова "Как уже не раз объяснялось". Их следует понимать буквально. Как уже не раз объяснялось, даже если в таком посте вы видите "обращение к вам лично", не реагируйте. Цель такого комментария заключается совсем в другом.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Вешать таблички без аргументов,
Снова проглядели. Там приведены конкретные и точные аргументы.



Добавлено через 7 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Он говорит, о том, что и С. Мейерс не советует перегружать шаблонные методы, а считает лучшим вариантом обычную перегрузку.
В данной теме пока не было абсолютно ничего даже отдаленно относящегося к той самой "несоветуемой" перегрузке шаблонных методов.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
25.04.2020, 13:01
zayats80888, отличный пример, кстати. Он же о том же. Компилятор не желает искать, если "трудновато".
Что касается типа из литерала - то это была литература. Я пробовал и именованные переменные до того. Я это написал в то смысле, что и ежику понятно что он int. И далее я привёл пример, где инстанс компилируется именно по "литералу". Который не даёт тут покоя товарищу, который не даёт покоя мне.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,226
25.04.2020, 15:16
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я это написал в то смысле, что и ежику понятно что он int. И далее я привёл пример, где инстанс компилируется именно по "литералу". Который не даёт тут покоя товарищу, который не даёт покоя мне.
Вам по-моему в первых же сообщениях дали ссылку на ясное и детальное описание понятия non-deduced context, которым исчерпывающе объясняется некомпилируемость исходного примера.

Как при этом было ясно сказано, проблема non-deduced context не имеет абсолютно никакого отношения ни к каким типам литералов int, независимо от того, понятны эти типы ёжикам или нет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.04.2020, 15:16
Помогаю со студенческими работами здесь

Перегрузка оператора << шаблонного класса
Всем доброго времени суток! Целый день бьюсь над перегрузкой оператора &lt;&lt; в шаблонном классе одномерный массив. Пока получилось родить...

Перегрузка оператора = в шаблоне класса
Доброго дня! Возник такой вот вопрос: я сделал шаблон класса и пытаюсь перегрузить его оператор присваивания, в итоге получается...

Перегрузка оператора для класса
Здравствуйте! Подскажите, пожалуйста, почему так не работает: class ClassA { public: ClassA() { m = 1; ...

Перегрузка оператора -> для шаблонного класса
Как это написать не понимаю помогите пожалуйста Добавлено через 23 секунды пример кода пожалуйста

Перегрузка оператора + для класса String
Подскажите, как реализовать перегрузку оператора сложения для класса String Вот, что пока получилось: #include &lt;iostream&gt; ...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки 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. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru