2015-11-26 5 views
0

Поэтому у меня есть некоторый базовый класс так:C++ шаблон класса, имеющий конструктор с шаблоном

template<class T1> 
class A { 
public: 
    X* x; 

    template <class T2> 
    A(const A<T2> &a) { 
     x = new X(a->x); 
    } 
}; 

Где как T1 и T2 будут иметь типы наследуемых от X. Тем не менее, этот код не работает и Я действительно не могу понять, как я буду писать его, чтобы конструктор смог взять еще A с потенциально различным аргументом шаблона.

Поэтому, чтобы было ясно, что я хочу написать конструктор, который принимает, будет иметь значение A с другим параметром шаблона. (Код компилируется как есть, часть шаблона просто не работает так, как я хочу).

То, что я хочу быть в состоянии сделать: (Где как Y и Z наследует от X)

A<Z> a1; 
A<Y> a2(a1); 

Любая помощь очень ценится!

Извините, я подумал, что смогу создать хороший пример и не должен использовать мой фактический код, но, похоже, я немного сработал с синтаксисом, так что вот мой настоящий класс немного сократил:

template <class T> 
class Calendar { 
private: 
    Date *d; 
public: 
    template <class T2> 
    Calendar(const Calendar<T2> &c) { 
     d = new T(c.view_date_component()); 
    } 
    Calendar(); 
    ~Calendar(); 
    const Date& view_date_component() const; 
}; 

template <class T> 
Calendar<T>::Calendar() { 
    d = new T(); 
} 

template <class T> 
Calendar<T>::~Calendar() { 
    delete d; 
} 

template <class T> 
const Date& Calendar<T>::view_date_component() const { 
    return *d; 
} 
+0

Как вы используете конструктор 'A'? вы можете создать небольшой 'main()', описывающий случай, и показать, какой результат вы ожидаете? –

+0

Это не имеет никакого отношения к шаблонам. Вы неправильно используете указатели и ссылки (например, используя '->' в ссылке). – interjay

+0

Для этого нужен конструктор по умолчанию. – 101010

ответ

1

Во-первых, вам также необходимо определить конструктор по умолчанию. Во-вторых, вам придется сделать класс шаблона другом для доступа к переменной частного члена x. В-третьих, в вашем конструкторе шаблонов вы передаете a как ссылка const. Следовательно, вы не можете получить доступ к его члену с помощью -> (т. Е. Оператор стрелки), а скорее с помощью . (т. Е. Оператор точки).

template<class T1> 
class A { 
    X* x; 
public: 
    A() = default; 
    ^^^^^^^^^^^^^^ 
    template <class T2> 
    A(const A<T2> &a) { 
    x = new X(*(a.x)); 
       ^^^^^^ 
    } 

    template<class T2> friend class A; 
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
}; 

Live Demo

Если вы хотите, чтобы конструктор шаблона быть вызван только если T1 и T2 унаследуют от X:

template <typename T2, 
typename = typename std::enable_if<std::is_base_of<X, T1>::value && 
            std::is_base_of<X, T2>::value>::type> 
A(const A<T2> &a) { 
    x = new X(*(a.x)); 
} 

Live Demo

+0

Даун-избиратели, пожалуйста, будьте любезны, чтобы объяснить причину вашего голосования. – 101010

0

Если вы хотите проверить, Т2 продолжается X или выдает T1, вы можете использовать SFINAE с std::is_base_of :

template <class T2, typename = std::enable_if_t<std::is_base_of<X, T2>>> 
A(const A<T2> &a) { 
    x = new X(a->x); 
} 
Смежные вопросы