Команда C ++ `using` для псевдонима типа в шаблонном классе

Кажется, это должно быть очень просто, но я играл и не нашел решения, которое искал, поэтому вот так:

У меня есть следующая структура (упрощенно для иллюстративных целей, конечно):

template<typename T>
struct test
{
using L = std::list<T>;
L::iterator a;
};

Теперь это выдает ошибку:

error: need 'typename' before 'test<T>::K::iterator' because 'test<T>::K' is a dependent scope

До сих пор я нашел два способа его устранения: они не идеальны:

1) добавить typename перед любым использованием L:

template<typename T>
struct test
{
using L = std::list<T>;
typename L::iterator a;
};

Я бы предпочел избежать дополнительной детализации этого, если это возможно.

2) добавьте еще один оператор using для непосредственного нацеливания на итератор:

template<typename T>
struct test
{
using L = std::list<T>;
using iter = typename L::iterator;
iter a;
};

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

Итак, есть ли способ написать оператор using, который затем позволяет мне написать:

 L::iterator a;
L::const_iterator b;
...

Спасибо!

4

Решение

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

template<typename C>
using Iterator = typename C::iterator;

template<typename C>
using ConstIterator = typename C::const_iterator;

template<typename T>
struct test
{
using L = std::list<T>;
Iterator<L> i;
ConstIterator<L> ci;
};
14

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

Нет, нет. Все зависимые типы должны иметь префикс typenameили быть введены через предисловие с typename,

Теперь вы можете создать list_iter<T> using декларация где-то:

template<typename T>
using list_iter = typename std::list<T>::iterator;

или даже оператор мета-iter, использующий:

template<template<typename>class container, typename T>
using iter = typename container<T>::iterator;
template<template<typename>class container, typename T>
using const_iter = typename container<T>::const_iterator;

что позволит вам сделать:

struct test {
using L = std::list<T>;
iter<std::list,T> a;
};

где я «спрятал» typename в using декларация вне struct,

Кроме того, в 99% случаев std::list это неправильный контейнер.

2

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