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

Объявить метод шаблонного класа как friend в другом классе

02.08.2020, 15:08. Показов 1580. Ответов 32
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Собственно возможно ли это ?
Насколько я помню что нет так как у метода шаблонного класса не может быть внешнего объявления, а только у специализвции.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2020, 15:08
Ответы с готовыми решениями:

Как объявить класс с переменной String^ в другом классе?
Доброго времени суток, уважаемые участники форума! Я работаю в Visual C++ 2008 Express, Windows...

Создать объект шаблонного класса в другом классе
Как создать объект шаблонного класса в другом классе и вызвать через этот объект функцию? class...

Нужно вызвать через сторонний метод(в другом классе,который в другом файле) метод в форме
public void Print_Inform(int numb1,int znak,int numb2) { switch(znak) { case 1:...

Как объявить массив объектов одного класса в другом классе, а затем поместить в него объекты?
Как объявить массив объектов одного класса в другом классе, а затем поместить в него объекты?

32
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 01:03 21
Author24 — интернет-сервис помощи студентам
oleg-m1973, да, это получается)
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
#include <iostream>
using namespace std;
 
class WhoIsMyFriend
{
    public:
    WhoIsMyFriend(int a_):a(a_){}
 
private:int a=0;
template<typename T>
friend
class Friend_templ ;
 
};
 
template<typename T>
struct Friend_templ
{
    void foo(const WhoIsMyFriend & who, const T& mess){
        cout<<who.a<<' '<<mess<<endl;
    }
};
 
int main()
{
WhoIsMyFriend mf(123);
Friend_templ<int> mint;
mint.foo(mf, 321);
Friend_templ<const char*> mcc;
mcc.foo(mf, "456");
return 0;
}
Добавлено через 43 минуты
и вот такой кошмарик. Это от бессонницы.
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
#include <iostream>
using namespace std;
 
class WhoIsMyFriend ;
 
template<typename T>
struct Friend_templ
{
    void foo(const WhoIsMyFriend & who, const T& mess);
};
 
class WhoIsMyFriend
{
    public:
    WhoIsMyFriend(int a_):a(a_){}
 
private:int a=0;
 
template<typename T>
friend
void Friend_templ<T>::foo(const WhoIsMyFriend & who, const T& mess);
};
 
template<typename T>
void Friend_templ<T>::foo(const WhoIsMyFriend & who, const T& mess){
       cout<<who.a<<' '<<mess<<endl;
    }
 
int main()
{
    WhoIsMyFriend mf(123);
    Friend_templ<int> mint;
    mint.foo(mf, 321);
    Friend_templ<const char*> mcc;
    mcc.foo(mf, "456");
return 0;
}
0
Вездепух
Эксперт CЭксперт С++
11695 / 6374 / 1724
Регистрация: 18.10.2014
Сообщений: 16,068
03.08.2020, 03:30 22
Цитата Сообщение от argcargv Посмотреть сообщение
Багрепорта про то, что Clang-у не нравится ::template template-id не замечено.
В Clang попытка указать 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
#include <iostream>
 
template <typename T> class B;
 
template <typename T> class A
{
  int i = 5;
 
public:
  template <typename U> void foo(B<U> &b) { b.i = 5; }
};
 
template <typename T> class B
{
  int i = 42;
  template <typename U> template <typename V> friend void A<U>::foo(B<V> &);
};
 
int main() 
{
  A<int> a;
  B<int> b;
  a.foo(b);
}
приводит к выдаче странного сообщения

Код
warning: dependent nested name specifier 'A<U>::' for friend class declaration is not supported; turning off access control for 'B' [-Wunsupported-friend]
Сообщение как бы намекает на то, что вся эта тема в Clang находится в состоянии "unsupported", то есть там пока что еще толком и конь не валялся.

При этом обещанного "turning off access control for 'B'" не происходит, т.е. доступ к B<>::i из A::foo не проходит.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 10:14 23
Вот шланг:
https://rextester.com/BUU55477
warning: dependent nested name specifier 'Friend_templ<T>::' for friend class declaration is not supported;
turning off access control for 'WhoIsMyFriend' [-Wunsupported-friend]
void Friend_templ<T>::foo(const WhoIsMyFriend & who, const T& mess);

Добавлено через 21 минуту
Фактически тупое отключение контроля доступа - приводит к ужасным последствиям. Вот этот код компилируется и работает на шланге:
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
#include <iostream>
using namespace std;
class WhoIsMyFriend ;
 
template<typename T>
struct Friend_templ
{
    void foo(const WhoIsMyFriend & who, const T& mess);
 
};
 
 
 
class WhoIsMyFriend
{
    public:
    WhoIsMyFriend(int a_):a(a_){}
 
private:int a=0;
 
template<typename T>
friend
void Friend_templ<T>::foo(const WhoIsMyFriend & who, const T& mess);
 
};
 
template<typename T>
void Friend_templ<T>::foo(const WhoIsMyFriend & who, const T& mess){
       cout<<who.a<<' '<<mess<<endl;
    }
 
int main()
{
 
WhoIsMyFriend mf(123);
Friend_templ<int> mint;
mint.foo(mf, 321);
Friend_templ<const char*> mcc;
mcc.foo(mf, "456");
    cout<<mf.a<<endl;////////////////////// gcc таких шуток не позволяет!
 
return 0;
Добавлено через 4 минуты
Microsoft Visual C++ 2019 нормально компилирует и работает на моей машине.
Visual C++ 2019 00435-60000-00000-AA687
Microsoft Visual C++ 2019

На сайте
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
не пропускает:
source_file.cpp(29): error C2248: 'WhoIsMyFriend::a': cannot access private member declared in class 'WhoIsMyFriend'
source_file.cpp(19): note: see declaration of 'WhoIsMyFriend::a'
source_file.cpp(15): note: see declaration of 'WhoIsMyFriend'
source_file.cpp(28): note: while compiling class template member function 'void Friend_templ<int>::foo(const WhoIsMyFriend &,const T &)'
with
[
T=int
]
source_file.cpp(37): note: see reference to function template instantiation 'void Friend_templ<int>::foo(const WhoIsMyFriend &,const T &)' being compiled
with
[
T=int
]
source_file.cpp(36): note: see reference to class template instantiation 'Friend_templ<int>' being compiled
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x64
0
248 / 70 / 9
Регистрация: 22.07.2018
Сообщений: 321
03.08.2020, 11:05 24
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В Clang попытка указать friend-а через "полное объявление" шаблона приводит к выдаче странного сообщения
Да, я это видел, для кода в #2.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Сообщение как бы намекает на то, что вся эта тема в Clang находится в состоянии "unsupported", то есть там пока что еще толком и конь не валялся.
Похоже на то.
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
При этом обещанного "turning off access control for 'B'" не происходит
Если B это класс, а не шаблон класса, то "turning off access control" таки происходит.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 11:47 25
oleg-m1973, вы изначально знали или угадали? :
https://rextester.com/OKLY5652
clang компилирует вариант с дружественным классом без проблем. Причём в этом случае достаточно объявления во внешнем скоупе без предварительного объявления)
msvs тоже работает тихо:
https://rextester.com/VKRONA32253
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
03.08.2020, 11:58 26
Цитата Сообщение от IGPIGP Посмотреть сообщение
oleg-m1973, вы изначально знали или угадали? :
В смысле, угадал? Я постоянно использую friend-классы, в том числе шаблонные. Вот friend-методы никогда не использовал.
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 11:59 27
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В смысле, угадал? Я постоянно использую friend-классы, в том числе шаблонные. Вот friend-методы никогда не использовал.
Я пошутил. А шаблонные френд-классы приходилось часто юзать?
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
03.08.2020, 12:06 28
Цитата Сообщение от IGPIGP Посмотреть сообщение
А шаблонные френд-классы приходилось часто юзать?
Ну да, довольно регулярно. А что?

Добавлено через 2 минуты
Вот, например, из последнего
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template 
<
    typename TNode, 
    typename... TParams
>
class __declspec(empty_bases) CList
: protected CListBase<TNode, List::CTraits<TParams...>>
{
using TBase = CListBase<TNode, List::CTraits<TParams...>>;
 
template <typename, typename...> friend class CList;
friend class CListIterator<CList>;
friend class CListIterator<const CList>;
public:
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 12:43 29
Выглядит внушительно. EBCO интересный зверь сам по себе. Внушительно. Скромно говоря. Приятно глазу)
Вообще, дружба простого класса с шаблоном, имеет нюанс. Интересный способ расширения функциональности простого класса.
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
03.08.2020, 12:50 30
Цитата Сообщение от IGPIGP Посмотреть сообщение
Вообще, дружба простого класса с шаблоном, имеет нюанс.
Ну да, становится гораздо проще получить доступ к приватным данным класса. Ну и ладно, они приватные не для супер-секретности.
0
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 13:19 31
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Ну да, становится гораздо проще получить доступ к приватным данным класса. Ну и ладно, они приватные не для супер-секретности.
Кроме того, это возможность "шаблонизировать" интерфейс, оставаясь простым классом. Самый простой и стандартный путь который я знаю - наследования шаблонным классом простого класса. Дружба - вроде более легкий, но ограниченный и ... босяцкий приём. Но есть и симпатичные стороны.
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
03.08.2020, 13:30 32
Цитата Сообщение от IGPIGP Посмотреть сообщение
Кроме того, это возможность "шаблонизировать" интерфейс, оставаясь простым классом.
В смысле, это как?
1
Комп_Оратор)
Эксперт по математике/физике
8949 / 4703 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
03.08.2020, 15:52 33
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В смысле, это как?
Как в примере, например. Функции друзья расширяют интерфейс класса. Шаблонные функции позволяют, это делать в стиле шаблонов.
Я задал вопрос о точном знании, пытаясь понять знали ли вы точно, что в постановке ТС задача налетит на рифы на ряде компиляторов. С предложенным вами решением всё получается, по крайней мере, на тройке самых-самых.
И решение, основанное на классе, решает вопросы любых методов путём добавления дополнительного уровня косвенного обращения. Обёртки например. С другой стороны интерфейс - настолько тонкий вопрос, как часть инкапсуляции, что написание специального шаблонного класса селектирующего уже существующие шаблоны как классов так и методов (if any), это вполне разумный шаг.
oleg-m1973, это просто мысли в слух на заданную тему.
Вам плюсы за очень чёткий ответ на старте темы.
0
03.08.2020, 15:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.08.2020, 15:52
Помогаю со студенческими работами здесь

Как объявить другом конкретный метод другого класса?
Как в одном классе объявить другом метод другого класса?

Как объявить friend функцию класса
как это оформить, чтобы работало // ----------&gt; one.h #include &quot;two.h&quot; #ifndef ONE_H_INCLUDED...

Наследование шаблонного класа
Здраствуйте. Помогите пожалуйста. Програма выдает ошибку C2512 и С2614 Я нормально...

Специализация шаблонного класа
Каким образом можно написать специализацию шаблонного класса так, чтобы часть методов являлась...

Как создать метод с использованием объекта другого метода, который определен в другом классе
В общем суть вот в чем: У меня есть 2 класса. 1 основный(Program) в нем в методе Main создается...

Как вызвать метод из одного класса чтобы он был виден в другом классе?(Отсылка от старой темы)
Добрый вечер,Я почти разобрался только у меня последний вопрос Как исправить?Смотрите скрин. Надо...


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

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru