从依赖基类访问类型

Tre*_*son 11 c++ templates dependent-name using-declaration

有谁知道为什么使用声明似乎不适用于从依赖基类导入类型名称?它们适用于成员变量和函数,但至少在GCC 4.3中,它们似乎被忽略了类型.

template <class T>
struct Base
{
  typedef T value_type;
};

template <class T>
struct Derived : Base<T>
{
  // Version 1: error on conforming compilers
  value_type get();

  // Version 2: OK, but unwieldy for repeated references
  typename Base<T>::value_type get();

  // Version 3: OK, but unwieldy for many types or deep inheritance
  typedef typename Base<T>::value_type value_type;
  value_type get();

  // Version 4: why doesn't this work?
  using typename Base<T>::value_type;
  value_type get(); // GCC: `value_type' is not a type
};
Run Code Online (Sandbox Code Playgroud)

我有一个基类,有一组allocator样式的typedef,我想在几个继承级别继承.到目前为止,我发现的最佳解决方案是上面的版本3,但我很好奇为什么版本4似乎不起作用.GCC接受使用声明,但似乎忽略它.

我检查了C++标准,C++程序.郎.第3版.[Stroustrup]和C++模板[Vandevoorde,Josuttis],但似乎都没有解决使用声明是否可以应用于依赖基类类型.

如果它有助于查看另一个示例,这里是在GCC邮件列表中被问到但没有真正回答的相同问题.提问者表示他已在其他地方看到"使用typename",但GCC似乎并不支持它.我没有其他符合标准的编译器可用于测试它.

Tre*_*son 10

正如Richard Corden指出的那样,在2003标准被批准之后,这个问题在C++标准核心语言缺陷报告中得到了解决:关键字typename/template如何与using-declarations交互?

拟议决议(2003年4月,2003年10月修订):

在7.3.3 [namespace.udecl]的底部添加一个新段落:

如果using声明使用关键字typename并指定依赖名称(14.7.2 [temp.dep]),则using-declaration引入的名称将被视为typedef-name(7.1.3 [dcl.typedef]) .

该文本似乎没有出现在2003年10月15日的第二版标准中.

GCC尚未实施此解决方案,如错误14258中所述:

-------评论#3来自Giovanni Bajo 2004-02-27 12:47 [回复] -------问题是我们的USING_DECL没有记录"typename",这就是事实它是一种通过它导入的类型.我相信这可以归功于隐式类型名称扩展.

重复错误21484表示'using typename'适用于Comeau和Intel编译器.因为MSVC将所有名称视为依赖,所以该编译器不需要(但允许)该构造.


已于2011年12月13日在GCC 4.7中修复!