Инстансирование шаблонного под-класса
От: nen777w  
Дата: 13.01.21 12:12
Оценка:
//h
template<typename T> struct foo { foo(); };
//cpp
template foo<int>;
template<typename T> foo<T>::foo() {}

//cpp
foo<int> obj; <-- OK

-------------------------------

//h
template<typename T> 
class foo 
{ 
  template<typename T2>
  struct doo
  {
     void method(T a);
  };
};
//cpp
template foo<int>::doo<void*>;

???
template<typename T>::template<T2> doo::method<T2>(T a)
{
}
Re: Инстансирование шаблонного под-класса
От: vopl Россия  
Дата: 13.01.21 12:29
Оценка: 4 (1)
Здравствуйте, nen777w, Вы писали:

//h
template<typename T> 
class foo 
{
public:
  template<typename T2>
  struct doo
  {
     void method(T a);
  };
};
//cpp

template struct foo<int>::doo<void*>;
template void foo<int>::doo<void*>::method(int);

//???
template<typename T>
template<typename T2>
void foo<T>::doo<T2>::method(T a)
{
  //
}

template<>
template<>
void foo<char>::doo<void*>::method(char a)
{
  //
}
Re[2]: Инстансирование шаблонного под-класса
От: nen777w  
Дата: 13.01.21 12:38
Оценка:
Здравствуйте, vopl, Вы писали:

V>Здравствуйте, nen777w, Вы писали:


  Скрытый текст
V>
V>//h
V>template<typename T> 
V>class foo 
V>{
V>public:
V>  template<typename T2>
V>  struct doo
V>  {
V>     void method(T a);
V>  };
V>};
V>//cpp

V>template struct foo<int>::doo<void*>;
V>template void foo<int>::doo<void*>::method(int);

V>//???
V>template<typename T>
V>template<typename T2>
V>void foo<T>::doo<T2>::method(T a)
V>{
V>  //
V>}

V>template<>
V>template<>
V>void foo<char>::doo<void*>::method(char a)
V>{
V>  //
V>}
V>


Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?
Re[3]: Инстансирование шаблонного под-класса
От: vopl Россия  
Дата: 13.01.21 14:56
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?


А предложи свой вариант?
Re[4]: Инстансирование шаблонного под-класса
От: nen777w  
Дата: 13.01.21 15:33
Оценка:
N>>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?
V>А предложи свой вариант?
Ну типа
template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
Отредактировано 13.01.2021 15:38 nen777w . Предыдущая версия . Еще …
Отредактировано 13.01.2021 15:37 nen777w . Предыдущая версия .
Отредактировано 13.01.2021 15:37 nen777w . Предыдущая версия .
Отредактировано 13.01.2021 15:35 nen777w . Предыдущая версия .
Отредактировано 13.01.2021 15:34 nen777w . Предыдущая версия .
Re[5]: Инстансирование шаблонного под-класса
От: vopl Россия  
Дата: 13.01.21 16:54
Оценка:
Здравствуйте, nen777w, Вы писали:

N>>>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?

V>>А предложи свой вариант?
N>Ну типа
N>
N>template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
N>


эмм... Наверное так?
void template<typename T> foo<T>:: template<typename T2> doo<T2>:: method(T a) {}


Точных причин не знаю, никогда не задумывался, но, что бросается в глаза: такой "вложенный" способ блокировал бы кейсы, в которых шаблонный аргумент используется ДО его объявления. Пример:

template<typename T> 
class foo 
{ 
  template<typename T2>
  struct doo
  {
     std::pair<T, T2> method(T a);
  };
};

// вложенный
std::pair<T, T2>                 //тип результата метода, но T и T2 еще не объявлены
template<typename T> foo<T>::    //объявление T, пространство foo::
template<typename T2> doo<T2>::  //объявление T2, пространство doo::
method(T a)                      //имя и аргументы метода
{}

// не вложенный
template<typename T>     //объявление T 
template<typename T2>    //объявление T2
std::pair<T, T2>         //тип результата метода, T и T2 уже были объявлены
foo<T>::                 //пространство foo::
doo<T2>::                //пространство doo::
method(T a)              //имя и аргументы метода
{}
Re[6]: Инстансирование шаблонного под-класса
От: vopl Россия  
Дата: 13.01.21 17:47
Оценка:
Здравствуйте, vopl, Вы писали:

  Скрытый текст
N>>>>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?
V>>>А предложи свой вариант?
N>>Ну типа
N>>
N>>template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
N>>


V>эмм... Наверное так?

V>
V>void template<typename T> foo<T>:: template<typename T2> doo<T2>:: method(T a) {}
V>


V>Точных причин не знаю, никогда не задумывался, но, что бросается в глаза: такой "вложенный" способ блокировал бы кейсы, в которых шаблонный аргумент используется ДО его объявления. Пример:


V>
V>template<typename T> 
V>class foo 
V>{ 
V>  template<typename T2>
V>  struct doo
V>  {
V>     std::pair<T, T2> method(T a);
V>  };
V>};

V>// вложенный
V>std::pair<T, T2>                 //тип результата метода, но T и T2 еще не объявлены
V>template<typename T> foo<T>::    //объявление T, пространство foo::
V>template<typename T2> doo<T2>::  //объявление T2, пространство doo::
V>method(T a)                      //имя и аргументы метода
V>{}

V>// не вложенный
V>template<typename T>     //объявление T 
V>template<typename T2>    //объявление T2
V>std::pair<T, T2>         //тип результата метода, T и T2 уже были объявлены
V>foo<T>::                 //пространство foo::
V>doo<T2>::                //пространство doo::
V>method(T a)              //имя и аргументы метода
V>{}
V>


Да и вообще, чуть шире — у объявления шаблонного аргумента и у самого шаблона — разные области применения. Объявление — должно случится один раз, а использование шаблона — много раз, причем объявленный Т не обязан использоваться, как бы это сказать, один-в-один. Соответственно, вполне логично разместить все объявления в самом начале, а потом уже их использовать в разных позах
Пример:

#include <utility>

template<typename T> 
class foo 
{ 
  template<typename T2>
  struct doo
  {
     std::pair<T, foo<doo<T2*>>> method(T a, foo, doo<foo>);
  };
};

template<typename T>
template<typename T2>
std::pair<T, foo<typename foo<T>::doo<T2*>> >
foo<T>::
doo<T2>::
method(T a, foo<T>, doo<foo<T>>)
{}


Вряд ли можно придумать такой "воженный способ", чтобы с его помощью можно было бы легко покрывать представленный кейс...
Re[5]: Инстансирование шаблонного под-класса
От: rg45 СССР  
Дата: 13.01.21 17:58
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Ну типа

N>
N>template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
N>


Гм... Я смотрю, void выскочило за пределы области видимости, непорядок. Нужно так:

template<typename T> foo<T>::template<T2> doo<T2>::void method(T a) {}
--
Не можешь достичь желаемого — пожелай достигнутого.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.