从依赖基类访问类型

时间:2009-07-01 20:12:42

标签: c++ templates using-declaration dependent-name

有谁知道为什么using声明似乎不适用于从依赖基类导入类型名称?它们适用于成员变量和函数,但至少在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
};

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

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

如果在GCC邮件列表中查看另一个示例here is the same question being asked,但没有真正回答,则有帮助。提问者表示他已在其他地方看到“使用typename”,但GCC似乎并不支持它。我没有其他符合标准的编译器可用于测试它。

2 个答案:

答案 0 :(得分:10)

正如Richard Corden所指出的那样,2003年标准批准后C++ Standard Core Language Defect Reports解决了这个问题:How do the keywords typename/template interact with using-declarations?

  

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

     

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

     

如果使用声明使用   关键字typename并指定一个   依赖名称(14.7.2 [temp.dep]),   这个名字由   using-declaration被视为a   typedef-name(7.1.3 [dcl.typedef])。

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

GCC尚未实施此决议,如bug 14258中所述:

  

-------评论#3来自Giovanni Bajo 2004-02-27 12:47 [回复] -------   问题是我们的USING_DECL没有   记录“typename”,即   事实上,它是一种类型   通过它进口。这曾经工作过   感谢隐式类型名称   延伸,我相信。

重复bug 21484表示'使用typename'适用于Comeau和Intel编译器。由于MSVC将所有名称视为依赖,因此该编译器不需要(但允许)该构造。


2011年12月13日在GCC 4.7中

Fixed

答案 1 :(得分:-2)

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