关于c ++:从依赖基类访问类型

Accessing types from dependent base classes

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
};

我有一个基类,其中包含一组分配器样式的typedef,我希望在继承的各个级别中继承这些typedef。到目前为止,我发现最好的解决方案是上面的版本3,但我很好奇为什么版本4似乎不起作用。GCC接受使用声明,但似乎忽略了它。

我已经检查了C++标准,C++ + PROG。Lang.第三Ed.[StruouStrup ]和C++模板[Vandevoorde,Jojuts],但似乎没有一个解决使用声明是否可以应用于依赖基类类型的问题。

如果它有助于看到另一个例子,那么在GCC邮件列表中有同样的问题被问到,但没有得到真正的回答。询问者表示他在其他地方看到过"使用类型名",但GCC似乎不支持。我没有另一个合格的编译器来测试它。


正如Richard Corden指出的,这个问题是在2003标准被批准后的C++标准核心语言缺陷报告中解决的:关键字类型名/模板如何使用声明交互?

Proposed resolution (April 2003,
revised October 2003):

Add a new paragraph to the bottom of
7.3.3 [namespace.udecl]:

If a using-declaration uses the
keyword typename and specifies a
dependent name (14.7.2 [temp.dep]),
the name introduced by the
using-declaration is treated as a
typedef-name (7.1.3 [dcl.typedef]).

2003年10月15日起,第二版标准中似乎没有出现此文本。

GCC还没有实现这个解决方案,如bug 14258所述:

------- Comment #3 From Giovanni Bajo 2004-02-27 12:47 [reply] ------- The
problem is that our USING_DECL doesn't
record the"typename", that is the
fact that it is a type which is
imported through it. This used to work
thanks to the implicit type name
extension, I believe.

重复的bug 21484表示"使用typename"适用于comeau和intel编译器。因为msvc将所有名称视为依赖项,所以该编译器不需要(但允许)构造。

2011年12月13日在GCC 4.7中修正!


在为base::value_类型声明typedef之前,您没有在base的模板中包含访问说明符(public/protected/private)。因此,它默认为private,并且在从base派生的类中不可访问。