Псевдоним для членов функции базового класса шаблона - PullRequest
0 голосов
/ 29 января 2019

Я пишу код, который использует много шаблонов, и я часто сталкиваюсь с кодом, который выглядит следующим образом:

template<class T, class V>
struct Base {  Base(int a) {} };

template<class T, class V>
struct Derived : public Base<T,V>
 {
 using Base<T,V>::Base; // [1] ok it works
 using Base::Base; // [2] Does not work  
 };

Подумайте, когда вы пишете вместо T более значимых имен, утверждение [1]становится слишком длинным .. нет ли способа использовать оператор, подобный [2]?или есть что-то, чтобы упростить это в будущих стандартах C ++?

Ответы [ 3 ]

0 голосов
/ 29 января 2019

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

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

template<class T, class V>
struct Derived : public Base<T,V>
 {
 using Derived::Base::Base;
 };

Derived найдено нормально (это имя введенного экземпляра этого экземпляра) и, как известно, является зависимым, поэтому известно, что Base в середине является зависимым и будет толькоискать при создании экземпляра Derived, когда все базы полностью известны и могут быть найдены.

0 голосов
/ 29 января 2019

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

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

template<class T, class V>
struct Derived : public Base<T,V>
{
    using Derived::Base::Base;
};

Derived - это имя внедренного класса Derived<T,V>.Итак, это найдено, и теперь мы делаем квалифицированный поиск для Base, поэтому его зависимость больше не является проблемой.

0 голосов
/ 29 января 2019

Вы можете определить псевдоним типа с помощью:

template<class T, class V>
struct Derived : public Base<T,V>
{
    using BaseClass = Base<T,V>;
    using BaseClass::Base;
};

Ключевое слово using имеет три значения в C ++.Он может вводить:

  • a директива использования ,
  • a декларация использования ,
  • или типпсевдоним.

A директива using имеет форму using namespace please_not_std и переносит все, что находится в пространстве имен please_not_std, в текущую область (этоупрощение).

A using-декларация имеет форму using Class::name и вводит имя, определенное в другом месте в текущей области.

* 1033Псевдоним типа * A (C ++ 11) имеет форму using new_type = existing_type и определяет ... псевдоним типа.
...