Здравствуйте, nen777w, Вы писали:
N>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)?
N>>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)? V>А предложи свой вариант?
Ну типа
template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
Здравствуйте, 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) //имя и аргументы метода
{}
N>>>>Интересно почему именно так. Ну в чем логика, почему бы в этом случае не соблюдать "вложенность" (если можно так сказать)? V>>>А предложи свой вариант? N>>Ну типа N>>
N>>template<typename T> foo<T>::template<T2> void doo<T2>::method(T a) {}
N>>
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>
Да и вообще, чуть шире — у объявления шаблонного аргумента и у самого шаблона — разные области применения. Объявление — должно случится один раз, а использование шаблона — много раз, причем объявленный Т не обязан использоваться, как бы это сказать, один-в-один. Соответственно, вполне логично разместить все объявления в самом начале, а потом уже их использовать в разных позах
Пример: