Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: template<typename U> friend class X ???  (Прочитано 16831 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
Aveic
Постоялец

ru
Offline Offline
Пол: Мужской
Yellow


« : 19-03-2008 10:52 » 

В книге Герба Саттера был пример в разделе «Управление памятью и ресурсами» про интеллектуальнаые указатели-члены. Приведу часть кода:
Код: (C++)
template<typename T>
class VPTraits
{
   static T* Clone(const T* p) { return new T(*p); }
};

template<typename T>
class ValuePtr
{
public:
   //... нешаблонные функции-члены

   template<typename U> ValuePtr(const ValuePtr<U>& other)
       :p_(CreateFrom(*other.p_)) {}

   template<typename U> ValuePtr& operator=(const ValuePtr<U>& other)
   {
       ValuePtr temp(other);
       Swap(temp);
       return *this;
   }

private:
   template<typename U> T* CreateFrom(const U* p) const
   {
       return p ? VPTraits<U>::Clone(p):0;
   }

   template<typename U> friend class ValuePtr;
 
   T* p_;
};
Так вот мне непонятно следующая строчка:
Код:
   template<typename U> friend class ValuePtr;
Понятно, что она объявляет друг класса. Только другом кому и когда это происходит.
Кто может поясните как можно подробней. Спс Улыбаюсь
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 19-03-2008 11:40 » 

Лично я не понял, откуда внутри класса ValuePtr берётся значение параметра U...
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sands
Помогающий

ua
Offline Offline

« Ответ #2 : 19-03-2008 11:54 » 

По-моему была такая заметка в правилах программирования на С++, где обьяснялось почему в шаблонном классе для конструктора используется не тот же параметр шаблона, а другой. Вот только, если чесно, я ее не запомнил((. Надо будет дома в книжице порыться...
Записан
Aveic
Постоялец

ru
Offline Offline
Пол: Мужской
Yellow


« Ответ #3 : 19-03-2008 12:49 » 

Лично я не понял, откуда внутри класса ValuePtr берётся значение параметра U...
Мне тоже непонятно. Упоминание о U есть только в операторе копирования и в копирующем конструкторе и в функции CreateFrom, которую вызывают две предыдущих ф-ии. Может после их вызова выясняется U и объявляется друг? Кароче не знаю.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 19-03-2008 15:33 » 

А, понял. Это будет типа:
Код: (C++)
ValuePtr<int> x<float>(otherInstance);

А зачем такое извращение?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Aveic
Постоялец

ru
Offline Offline
Пол: Мужской
Yellow


« Ответ #5 : 19-03-2008 18:56 » 

А, понял. Это будет типа:
Код: (C++)
ValuePtr<int> x<float>(otherInstance);

А зачем такое извращение?
после этого Value<int> будет другом для Value<float> Не понял
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 19-03-2008 21:12 » 

Это ещё почему? Я вообще смысла строчки с friend не понимаю. Если бы параметр U использовался в этой строчке - было бы понятно, а так - совершенно непонятно, зачем он там. Этот шаблон после специализации вообще собирается? Я бы на месте компилятора обиделся на ValuePtr без параметров.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Aveic
Постоялец

ru
Offline Offline
Пол: Мужской
Yellow


« Ответ #7 : 20-03-2008 02:29 » 

в общем вопрос отстается открытым!
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 20-03-2008 04:13 » 

Другом объявляется любой шаблонный класс ValuePtr с одним параметром шаблона, вот и всё.
Что касается буквы U так это просто обявление шаблона внутри шаблона, т.е. U в методах никак не зависит от T класса
букву T нельзя использовать, т.к. она используется в обявлении шаблона класса, это требует стандарт
Если всё же решите, использовать T для методов то внутри метода будет не понятно, какой T, это параметр шаблона класса или параметр шаблона метода класса, впрочем VS++ допускает подобное использование и использует T из шаблона метода, но gcc пошлёт всех стройными ряда в известном направлении
Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #9 : 20-03-2008 06:55 » new

LogRus, выходит что можно делать так?

Код:
typedef ValuePtr<int>        IntValPtr;
typedef ValuePtr<double> DblValPtr;

IntValPtr   iptr;
DblValPtr  dptr;

ip = <double> dptr; // dptr - друг, есть доступ к  T* p_;


Не понял
Записан

while (8==8)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 20-03-2008 07:05 » 

Цитата: LogRus
букву T нельзя использовать, т.к. она используется в обявлении шаблона класса, это требует стандарт
Если всё же решите, использовать T для методов то внутри метода будет не понятно, какой T, это параметр шаблона класса или параметр шаблона метода класса, впрочем VS++ допускает подобное использование и использует T из шаблона метода, но gcc пошлёт всех стройными ряда в известном направлении
Не понял.
Код: (C++)
#include <iostream>

template<class T>
class X
{
public:
        T &transit(T &a);
};

template<class T>
T &X<T>::transit(T &a)
{
        return a;
}

int main()
{
        int y = 3, z = 0;
        X<int> x;      
        z = x.transit(y);
        std::cout << z << std::endl;
        return 0;
}
Код:
$ gcc -dumpversion
4.1.2
$ g++ -o test.out test.cpp
$ ./test.out
3

Или ты имеешь в виду, что вложенный параметр шабона не должен перекрывать внешний?

А кому это вообще надо? Кому в голову приходит такая мысль?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 20-03-2008 07:08 » 

Цитата: sss
ip = <double> dptr;
Чего-то сильны мои сомнения. Вот если бы
Код: (C++)
ip.operator=<double>(dptr);
это ещё куда ни шло.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
sss
Специалист

ru
Offline Offline

« Ответ #12 : 20-03-2008 07:35 » 

dimka, я и не спорю...

Я просто вспомнил, что пользую так,

T* p = const_cast<T*>( const T*)

вот и подумал что синтаксис такой же...
Записан

while (8==8)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #13 : 21-03-2008 05:39 » 

Или ты имеешь в виду, что вложенный параметр шабона не должен перекрывать внешний?

А кому это вообще надо? Кому в голову приходит такая мысль?

Ага, параметры вложенных шаблонов, не должны перекрывать внешение.
Насчет того, кому это в голову придёт Улыбаюсь ну так я уже встречал код в котором приходило народу в голову так делать, т.к. T это такое удобное название Улыбаюсь
Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines