是否需要typename?

时间:2015-05-31 05:18:34

标签: c++ templates c++11 language-lawyer typename

考虑代码:

#include <memory>

template <class T, class Deleter = std::default_delete<T>>
class unique_ptr_wrapper: public std::unique_ptr<T, Deleter>
{
public:
    using typename std::unique_ptr<T, Deleter>::unique_ptr;
    operator T* () const {return this->get();}
};

int main()
{
    unique_ptr_wrapper<int> upw{new int{42}};
}
尽管clang ++抱怨

,但是g ++ 5.1编译得很好
  

错误:仅允许使用typename

我同意我们这里没有标识符,因此可能不需要typename。但它真的被禁止了吗?是否需要编译器至少发出诊断信息?

编辑 g ++和clang ++都没有typename编译好代码。

更新这似乎是一个g ++错误,我报告了它here

1 个答案:

答案 0 :(得分:8)

[class.inhctor] / p1,强调我的:

  

using-declaration (7.3.3)隐含地命名构造函数   声明一组继承构造函数

构造函数不是类型。

[temp.res] / P3-4:

  

3当 qualified-id 旨在引用不是a的类型时   当前实例化的成员(14.6.2.1)及其成员    nested-name-specifier 是指依赖类型,它应以关键字typename作为前缀,形成一个typename-specifier。如果    typename-specifier 中的 qualified-id 不表示类型,   该计划格式不正确。

     

4如果为一组实例化实例化模板的特化    template-arguments ,以typename为前缀的 qualified-id 不表示类型,专业化不正确。   通常的限定名称查找(3.4.3)用于查找    qualified-id 即使存在typename

[class.qual] / P2:

  

在查找中,不忽略函数名称和    nested-name-specifier 指定一个类C

     
      
  • 如果在C中查找 nested-name-specifier 之后指定的名称,则是的注入类名称 C(第9条)或

  •   
  • using-declaration (7.3.3) member-declaration 中,如果在嵌套名称后指定的名称 - 说明符与...相同   标识符 simple-template-id 模板名称   嵌套名称说明符的最后一个组件,

  •   
     

而是将名称视为命名类C的构造函数。

应用[class.qual]中的“通常限定名称查找”规则,std::unique_ptr<T, Deleter>::unique_ptr命名构造函数。它不表示类型。因此,根据[temp.res]的上述引用,该程序格式错误(需要诊断)。

换句话说,这似乎是一个GCC错误(虽然Clang的错误信息也可以使用一些改进)。