0

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

Какой правильный синтаксис для указания использования конкретного конструктора, когда тип имеет Dual? В частности, мне нужно инициализировать элемент «real» в списке инициализаторов, когда параметр шаблона имеет тип Dual, но не тогда, когда он отсутствует (например, тип double).

template<class X> class Dual { 
public: 
    X real; 
    size_t N; 
    std::vector<X> imag;//don't know N at compile time 


    Dual(size_t _N); 

}; 

template <class X> 
inline Dual<X>::Dual(size_t _N): N(_N), imag(N, 0.0) {} 

template <class X> 
inline Dual<Dual<X> >::Dual(size_t _N): real(_N), N(_N), imag(_N, 0.0) {} 
//syntax error: 
//error: cpptest.cpp:20:24: error: C++ requires a type specifier for all declarations 
//inline Dual<Dual<X> >::Dual(size_t _N): real(_N), N(_N), imag(_N, 0.0) {} 
//~~~~~~ 



int main(){ 

    Dual <double> a(5); 
    Dual< Dual < double>> b(5); 

} 
+0

Связанная, но не прямая причина: у вас нет конструктора по умолчанию. Как вы относитесь к построению по умолчанию типа без конструктора по умолчанию, как в своем вложенном объявлении? –

+0

Это проблема, которую я пытаюсь решить со специализацией. Тип X является либо Двойным , который требует вызова конструктора аргументов 1 или его типа с плавающей запятой, и в этом случае это не так (значение назначается позже). –

+0

Должно быть очевидно: Добавьте конструктор по умолчанию в свой класс 'Dual'. –

ответ

1

Вы можете предоставить свой конструктор с дополнительным вторым параметром инициализации real.

template<class X> class Dual { 
public: 
    X real; 
    size_t N; 
    std::vector<X> imag; 
    Dual(size_t _N, X x = X()); 
}; 

template <class X> 
inline Dual<X>::Dual(size_t _N, X x): real(x), N(_N), imag(N, 0.0) {} 

Теперь, когда у вас есть специальный Dual, вы можете инициализировать его так, как вы хотите, переходя в «прототип».

Dual<double> a(5); 
Dual< Dual<double> > b(5, a); 

Преимущество заключается в том, что у вас есть только объявить один template. Однако, если вы создадите специализацию для Dual< Dual<X> >, вы можете определить конструктор, как вы пробовали (за исключением того, что инициализация была неправильной и исправлена ​​ниже).

// Specialize Dual<T> in the case T is a Dual<X> 
template <class X> class Dual< Dual<X> > { 
public: 
    Dual<X> real; 
    size_t N; 
    std::vector< Dual<X> > imag; 
    Dual(size_t _N); 
}; 

template <class X> 
inline Dual< Dual<X> >::Dual(size_t _N) 
    : real(_N), N(_N), imag(N, Dual<X>(_N)) {} 
0

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

+0

Можете ли вы рассказать о том, почему конструктор является непиговым шаблоном? –

+0

@BenJones: Конструкторы не являются типами. Вы можете только частично специализировать типы. С другой стороны, вы можете полностью специализировать функции членов шаблона, но это должна быть полная специализация. В вашем случае вы пытаетесь частично специализировать конструктор для 'Dual ' (для любого 'X'). –