2016-07-14 3 views
-1

У меня есть следующие классыC++ 11 псевдонимов и шаблон шаблона

struct Abis 
{ 
    void foo() { // does something } 
}; 

struct A 
{ 
    typedef Abis bis_type; 
    bis_type create() { // instanciates Abis object }; 

}; 

template<class Tbis> // typically Tbis would be Abis 
struct Bbis 
{ 
    // something 
}; 

template<class T> // typically T would be A 
struct B 
{ 
    typedef Bbis<typename T::bis_type> bis_type; 
    bis_type create() { // instanciates Bbis object }; 
}; 

Теперь я хотел бы добавить еще один слой:

template<class Tbis, template<class> class Ubis> 
struct Cbis : public Ubis<Tbis> 
{ 
    void additional_method() { // does something calling Tbis and Ubis methods} 
}; 

и имеет класс С экземпляром объекта CBIS поэтому я может написать что-то вроде этого:

C<A,B> c(); 
Cbis<Abis,Bbis> cbis = c.create(); 
cbis.additional_method(); 

Это требует быть в состоянии обратиться к ЬурейеМу bis_types, так что я попробовал этот

template<class T, template<class> class U> 
struct C 
{ 
    template<class S> 
    using Ubis_type = U<S>::bis_type // PROBLEM! 
    typedef Cbis<typename T::bis_type,Ubis_type> bis_type; 

    bis_type create(); 
} 

Это не похоже на работу и ни делает

template<class T, template<class> class U> 
struct C 
{ 
    template<class S> 
    using Ubis_type = typename U<S>::bis_type // PROBLEM! 
    typedef Cbis<typename T::bis_type,Ubis_type> bis_type; 

    bis_type create(); 
} 

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

Является ли мой синтаксис правильным? (Я использую XCode 7.3)

Благодарности

+0

вы уже прочь к неправильному началу, даже прежде чем вы вышли из ворота: 'ЬурейеГо Bbis bis_type;' - «Bbis» - не тип. Это шаблон. Большая разница. Конечно, «U » - «ПРОБЛЕМА!» В любом месте нет шаблона U. Все это выглядит как фэнтезийный код, а не настоящий код. –

+0

* «Это не работает, и не« * », включая сообщения об ошибках –

+0

template // Это не имеет смысла, поскольку вы вообще не используете класс T ... – nosbor

ответ

0

Основная проблема с вашей typedef Bbis bis_type линии - Bbis является шаблоном класса, а не класс. Я думаю, что, скорее всего, вы имеете в виду typedef Bbis<T> bis_type (учитывая, что в этом контексте у вас есть тип T). После этого, ваш код в основном работает (я должен был исправить несколько опечаток, чтобы получить его для компиляции), вот окончательный вариант:

(UPDATE: измененного определения struct C в соответствии с требуемым использованием при C<A, B>)

struct Abis 
{ 
    void foo() { // does something 
    } 
}; 

struct A 
{ 
    typedef Abis bis_type; 
    bis_type create() { // instanciates Abis object 
    return Abis(); 
    } 

}; 

template<class Tbis> // typically Tbis would be Abis 
struct Bbis 
{ 
    // something 
}; 

template<class T> // typically T would be A 
struct B 
{ 
    typedef Bbis<T> bis_type; 
    bis_type create() { // instanciates Bbis object 
    }; 
}; 

template<class Tbis, template<class> class Ubis> 
struct Cbis : public Ubis<Tbis> 
{ 
    void additional_method() { // does something calling Tbis and Ubis methods 
    } 
}; 

template<class T, template<class> class U> 
struct C 
{ 
    template<class S> 
    using Ubis_type = typename U<S>::bis_type; // PROBLEM! 

    typedef Cbis<typename U<T>::bis_type,Ubis_type> bis_type; 

    bis_type create() 
    { 
     return bis_type();  
    } 
}; 

Затем вы можете использовать свой окончательный struct C так:

int main(int argc, char**args) 
{ 
    C<A, B> c; 
    auto d = c.create(); 

    d.additional_method(); 

    return 0; 
} 
+0

спасибо за ответ. Я отредактировал свое сообщение, чтобы исправить определение B :: bis_type (это было правильно определено в моем фактическом коде, поэтому это не проблема). Я также привел пример конечного результата, к которому я стремился. – AFK

+0

Смотрите мои правки выше. Теперь вы можете использовать 'C '. Примечание: ваш (ручной) вывод возвращаемого типа 'C :: create()' был неправильным. Однако вы можете просто использовать 'auto' и не беспокоиться об этом. Конечный объект 'd' отлично подходит для использования и может вызывать на нем' дополнительный_метод', как вы можете видеть в моем ответе – Smeeheey

+0

Итак, вы говорите, что мой синтаксис верен, если я использую typename для зависимого типа? – AFK

Смежные вопросы