C++模板类中用于类型别名的`using`命令

5

这似乎应该很简单,但我已经尝试了一些方法还没有找到我要的解决方案,所以现在就来提问:

我有一个下面这个结构体(当然这里只是为了说明目的而简化了):

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) 在 L 的任何使用前添加 typename:
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语句。因此,是否有一种方法可以编写using语句,然后允许我编写以下内容:
 L::iterator a;
 L::const_iterator b;
 ...

谢谢!

2个回答

15

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;
};

感谢您的回答!鉴于不能按照我喜欢的方式做,这似乎是最简洁的方法 :) - jsdw

2
没有,所有依赖类型都必须以 typename 开头或通过前缀 typename 引入。
现在,你可以在某个地方创建一个 list_iter<T>using 声明:
template<typename T>
using list_iter = typename std::list<T>::iterator;

甚至可以使用元迭代器的语句:
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;
};

我已经在struct之外的using声明中“隐藏”了typename

顺便说一下,99%的情况下,std::list都是错误的容器选择。


1
我认为这不会起作用,因为std::list还接受一个额外的分配器类型参数(它有一个默认参数)。 - Andy Prowl
谢谢你的回答!关于使用列表,这将是一个可能非常大的符号列表,经常需要在其他位置保存(因此遍历列表以查找它们不是问题)进行删除或插入;我认为这是那些1%的情况之一 :) - jsdw
如果您在删除元素之前遍历list以查找它们,并且它们并不都聚集在列表的前面或附近,则vector仍然更有效。要使list胜出,您基本上需要从中添加和删除元素而无需遍历以查找元素,因为“移动”向下在vector中的元素的成本通常比遍历list的成本更便宜!(昂贵的移动(即不移动和大型复制)元素也可能使list更具诱惑力,但即使在这种情况下,deque也会胜出...)如果您没有进行性能分析,则是错误的。 - Yakk - Adam Nevraumont

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接