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派生的类中不可访问。