This seems like it should be really simple, but I've been playing and havn't found the solution I'm looking for yet, so here goes:
这看起来应该很简单,但我一直在玩,并没有找到我正在寻找的解决方案,所以这里有:
I have the following struct (simplified for illustrative purposes of course):
我有以下结构(当然为了说明目的而简化):
template<typename T>
struct test
{
using L = std::list<T>;
L::iterator a;
};
Now, this throws the error:
现在,这会引发错误:
error: need 'typename' before 'test<T>::K::iterator' because 'test<T>::K' is a dependent scope
The two ways I have found of fixing it so far are both less than ideal:
到目前为止,我发现修复它的两种方法都不太理想:
1) add typename before any use of L:
1)在使用L之前添加typename:
template<typename T>
struct test
{
using L = std::list<T>;
typename L::iterator a;
};
I'd rather avoid the extra verbosity of this if possible.
如果可能的话,我宁愿避免这种额外的冗长。
2) add another using statement to target the iterator directly:
2)添加另一个using语句直接定位迭代器:
template<typename T>
struct test
{
using L = std::list<T>;
using iter = typename L::iterator;
iter a;
};
But that would require having to do the same for every iterator I wanted to use, if I also wished to access the const_iterator
etc etc, and I'd rather not have to define a bunch of using statements.
但是,如果我还希望访问const_iterator等,那么就需要对我想要使用的每个迭代器都做同样的操作,而我宁愿不必定义一堆using语句。
So, is there a way to write the using statement that then allows me to write:
那么,有没有办法编写using语句,然后允许我写:
L::iterator a;
L::const_iterator b;
...
Thanks!
2 个解决方案
#1
14
The typename
must be there, but you can use a couple of alias template utilities to avoid defining a new iter
type every time:
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;
};
#2
2
Nope, there is not. All dependent types must either be prefaced with typename
, or be brought in via a preface with typename
.
不,没有。所有依赖类型必须以typename开头,或者通过带有typename的前言引入。
Now, you could create a list_iter<T>
using
declartion somewhere:
现在,您可以在某处使用declartion创建list_iter
template<typename T>
using list_iter = typename std::list<T>::iterator;
or even a meta-iter using statement:
甚至是使用声明的meta-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;
which would let you do:
这会让你这样做:
struct test {
using L = std::list<T>;
iter<std::list,T> a;
};
where I've "hidden" the typename
in a using
declaration outside of the struct
.
我在结构之外的using声明中“隐藏”了typename。
As an aside, 99% of the time std::list
is the wrong container.
另外,99%的时间std :: list是错误的容器。
#1
14
The typename
must be there, but you can use a couple of alias template utilities to avoid defining a new iter
type every time:
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;
};
#2
2
Nope, there is not. All dependent types must either be prefaced with typename
, or be brought in via a preface with typename
.
不,没有。所有依赖类型必须以typename开头,或者通过带有typename的前言引入。
Now, you could create a list_iter<T>
using
declartion somewhere:
现在,您可以在某处使用declartion创建list_iter
template<typename T>
using list_iter = typename std::list<T>::iterator;
or even a meta-iter using statement:
甚至是使用声明的meta-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;
which would let you do:
这会让你这样做:
struct test {
using L = std::list<T>;
iter<std::list,T> a;
};
where I've "hidden" the typename
in a using
declaration outside of the struct
.
我在结构之外的using声明中“隐藏”了typename。
As an aside, 99% of the time std::list
is the wrong container.
另外,99%的时间std :: list是错误的容器。