2013-03-02 3 views
1

Предположим, файл заголовка myheader.hxx определяет шаблон класса A, в котором, не шаблонный класс B определен (который не зависит от параметра шаблона из A):Могут ли внедряться вложенные классы шаблонов классов в заголовок C++?

template<class T> 
class A { 
    class B { 
     // ... 
    }; 
}; 

это хорошо в этом случае для реализации B в myheader.hxx, или мне нужно написать отдельный myheader.cxx, чтобы избежать дублирования определений во время ссылки? Является ли этот случай последовательно обработан различными компиляторами?

+1

'B' действительно зависит от параметра шаблона' в вашем Т *. Например, Не напрямую, а 'A :: B' и' A :: B' - несвязанные типы. – Yakk

+1

Наверное, не имеет значения, но я думаю, что 'typename T' предпочитает' class T' в настоящее время. По крайней мере, это то, что «классные дети», похоже, делают. –

+0

@ StephenLin - да, некоторые люди считают, что здесь полезно использовать «typename», но «класс» правильный, короче, и это способ, которым стандарт C++ пишет шаблоны. Нет хорошей технической причины использовать 'typename' вместо' class'. –

ответ

0

Он по-прежнему является либо шаблоном (или частью шаблона, не знает сверхточных определений), даже если он не является шаблоном верхнего уровня, поэтому вы должны необходимо, чтобы должен реализовать его в заголовке (технически, он может быть в исходном файле, если это единственное место, которое он использует, но это, вероятно, побеждает цель).

Примечание: если вы не собираетесь выполнять свои функции-члены рядный с определением класса, вам нужно синтаксис как:

template<typename T> 
void A<T>::B::foo(...) 
{ 
    // ... 
} 

Кроме того, потому что это придумали раньше, если B случилось иметь свой собственный шаблон параметра, это будет что-то вроде:

template<typename T> 
template<typename T2> 
void A<T>::B<T2>::foo(...) 
{ 
    // ... 
} 

Не:

template<typename T, typename T2> 
void A<T>::B<T2>::foo(...) 
{ 
    // ... 
} 

Или если B не сделал, но B::foo сделал, это было бы:

template<typename T> 
template<typename T2> 
// void A<T>::B::foo<T2>(...) // not this apparently 
void A<T>::B::foo(...) 
{ 
    // ... 
} 

EDIT: по-видимому, это foo выше вместо foo<T2> для функции, по крайней мере, с GCC (так что почти 100% уверен, что это стандарт поведение) ... Я уверен, что некоторый язык адвокат будет в состоянии объяснить, почему :)

Etc.