Кажется, это должно быть очень просто, но я играл и не нашел решения, которое искал, поэтому вот так:
У меня есть следующая структура (упрощенно для иллюстративных целей, конечно):
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;
...
Спасибо!
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;
};
Нет, нет. Все зависимые типы должны иметь префикс 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
это неправильный контейнер.