Использование объявления для типозависимого имени шаблона

Когда CRTP используется внутри шаблона (или, как правило, когда параметр шаблона передается в качестве аргумента шаблона базового класса), невозможно назвать шаблоны-члены базы в using декларация?

template< typename d >
struct base {
template< typename >
struct ct {};

template< typename >
void ft() {}
};

template< typename x >
struct derived : base< derived< x > > {
using derived::base::template ct; // doesn't work
using derived::base::ft; // works but can't be used in a template-id
};

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

using-declaration:
using typename(opt) nested-name-specifier unqualified-id ; // have this
using :: unqualified-id ;

unqualified-id:
identifier
operator-function-id
conversion-function-id
literal-operator-id
~ class-name
~ decltype-specifier
template-id

qualified-id:
nested-name-specifier template(opt) unqualified-id // want this
:: identifier
:: operator-function-id
:: literal-operator-id
:: template-id

Если бы единственное правило было using-declaration: using typename(opt) qualified-id, единственные последствия будут

  • исключая :: conversion-function-id, :: ~ class-name, а также :: ~ decltype-specifier template-id которые не имеют смыслового смысла,
  • позволяющий :: template-id что уже прямо запрещено 7.3.3 / 5, и
  • позволяя template ключевое слово, которое уже имеет достаточную спецификацию для исправления дыры.

Является ли этот анализ правильным?

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

     using typename derived::base::template ct;
using derived::base::ft;

Это может потребовать некоторых дополнительных спецификаций. Кроме того, текущим статус-кво кажется, что зависимые имена шаблонов всегда имеют неоднозначный вид (не шаблоны-идентификаторы), поэтому не ясно, что typename принадлежит с ct совсем.

14

Решение

Следующее прекрасно работает с C ++ 11:

#include <iostream>

template< typename d >
struct base {
template< typename >
struct ct {};

template< typename >
void ft() {std::cerr << "cheesecake" << std::endl;}
};

template< typename x >
struct derived : base< derived< x > > {
template<typename X>
using ct = typename derived::base::template ct<X>; // new in C++11
using derived::base::ft;
};

int main()
{
derived<int>::ct<float> c;
derived<int> a;
a.ft<int>();
}

Если это не то, что вы хотели, не могли бы вы привести пример того, как вы хотели бы использовать Коннектикут а также фут?

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]