Как решить проблему безымянного поиска имени

У меня есть следующая упрощенная программа:

class Base { };

template < typename T >
class X: public T
{
    public:
        using TOP = T;
};

// with dependent template parm    
template < typename T >
class Y: public X< T >
{
    // I have to write down the full name of the base class
    using X<T>::TOP::operator =;
};

// without depending template parameter
template < typename T >
class Y: public X< Base >
{
    // I simply can use the defined type from the base class
    using TOP::operator =;
};


int main()
{
    Y< Base > y ;
}

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

template < typename VAR_TYPE >
class VarObserved: public ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >
                   >
{
    public:
        using SELF = ConstructAll2<
            UsingHelperV_None,
            UsingHelper_None,
            CONTAINERL< AssignConst >,
            CONTAINERL< Print >,
            CONTAINERL< DataStore >,
            CONTAINERL< Distribute_ >, 
            CONTAINERL< EndForward     >,
            CONTAINERSP< DataStoreBase, VAR_TYPE >   // see text 1)
                >;

        VarObserved( const VAR_TYPE& var ): SELF{{ var }}{}
        using SELF::AssignConst::operator=;
};

Как видите, полное повторение всех параметров шаблона не очень "приятно". Есть ли шанс исправить это?

Если приведенный выше код не имеет зависимого параметра шаблона (измените одну строку 1.)) из приведенного выше примера на:

CONTAINERSP< DataStoreBase, int>

класс становится полностью простым и гораздо более легким в обслуживании:

...
VarObserved( const VAR_TYPE& var ): ConstructAll2{{ var }}{}
using AssignConst::operator=;
....

В качестве ссылки на основную проблему я уже нашел этот вопрос

"не объявлено в этой области" ошибка с шаблонами и наследованием

но понятия не имею, чтобы упростить мой код.

3 ответа

Решение

Вопрос сейчас в том, есть ли способ упростить полное повторение типа базового класса.

Чтобы найти имя TOP объявленный в зависимом базовом классе, вы можете написать Y::TOP вместо X<T>::TOPХотя это может запутать читателей, вам, вероятно, следует оставить комментарий о том, почему вы это делаете.

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

Может быть, использовать новый параметр шаблона со значением по умолчанию (исправлено после наблюдения Джастина)?

template <typename VAR_TYPE, typename CA2 = ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >>>
class VarObserved : public CA2
 {
    public:
        using SELF = CA2;

        VarObserved( const VAR_TYPE& var ): SELF{{ var }}{}
        using SELF::AssignConst::operator=;
 };

В дополнение к идее от max66 я нашел также следующее решение, основанное не на специализации, а на параметре шаблона шаблона:

template < typename VAR_TYPE >
using VarObserved_Parms = ConstructAll2<
    UsingHelperV_None,
    UsingHelper_None,
    CONTAINERL< AssignConst >,
    CONTAINERL< Print >,
    CONTAINERL< DataStore >,
    CONTAINERL< Distribute_ >,
    CONTAINERL< EndForward >,
    CONTAINERSP< DataStoreBase, VAR_TYPE >
    >;

template < typename VAR_TYPE, template <typename> class COMPONENTS >
class VarObserved2: public COMPONENTS< VAR_TYPE >
{
    using SELF = COMPONENTS< VAR_TYPE >;

    VarObserved2( const VAR_TYPE& var ): SELF{{ var }}{}
    using SELF::AssignConst::operator=;
};

После того, как я получил идею от Брайана, все практически исчезает:

template < typename VAR_TYPE >
class VarObserved: public ConstructAll2<
                   UsingHelperV_None,
                   UsingHelper_None,
                   CONTAINERL< AssignConst >,
                   CONTAINERL< Print >,
                   CONTAINERL< DataStore >,
                   CONTAINERL< Distribute_ >,
                   CONTAINERL< EndForward >,
                   CONTAINERSP< DataStoreBase, VAR_TYPE >
                   >
{
    public:
        VarObserved( const VAR_TYPE& var ): VarObserved::ConstructAll2{{ var }}{}
                                            ^^^^^^^^^^^^^ never saw that before, interesting syntax ;)
        using VarObserved::AssignConst::operator=;
};
Другие вопросы по тегам