类模板的注入类名称

时间:2014-10-25 01:30:03

标签: c++ templates language-lawyer

the code in this answer的启发。考虑:

template<class>
class A { };

int main()
{
    A<float> a(A<float>::A<int>());
    return 0;
}

这是代码吗

  1. 格式错误,因为A<float>::A命名构造函数(根据§3.4.3.1[class.qual] / p2)并且不能在此上下文中使用(加上<int>将完成无法解析无论如何),或
  2. 格式正确,A<float>::A注入类名,用作模板名称(§14.6.1[temp.local] ]),A<float>::A<int>表示与A<int>完全相同,a被声明为函数(由于最令人烦恼的解析)?
  3. g++ says 1. clang says 2ICC 13也一样。哪个编译器是正确的?

1 个答案:

答案 0 :(得分:6)

gcc是正确的;你的片段格式不正确!

// reduced testcase
template<class T>
class A { };

int main () {
  A<float>::A<int> x; // ill-formed, bug in `clang` and `icc`
}

在上面的简化测试用例中,我们有一个嵌套名称说明符A<float>::,后跟一个 unqualified-id A,其中然后是一些乱码(<int>)。

这是因为嵌套名称说明符出现的上下文要求在查找期间包含函数名称(意味着首先找到构造函数,表达式为不良形成的)。


相关错误报告


如何规避&#34; 问题&#34;?

有些上下文通过 nested-name-specifier (提名类)查找的成员名称不应包含函数(因此,找不到构造函数的上下文),以下是一些例子:

template<class T>
struct A {
  typedef T value_type;
};
  struct A<float>::A<int>  x;     // ok, context: elaborate-type-specifier
typename A<float>::A<int> ();     // ok, context: [expr.type.conv]p1
  A<float>::A::value_type  x;     // ok, context: nested-name-specifier


struct X : A<float>::A<int> { };  // ok, context: base-specifier

标准说什么?

  

3.4.3.1p2 班级成员 [class.qual]

     
    

在不忽略函数名称的查找 88 嵌套名称说明符指定类 C

         
        
  • 如果嵌套名称说明符之后指定的名称(在 C 中查找)是 C 的注入类名称>(第9条)或
  •     
  • using-declaration (7.3.3)中是 member-declaration ,如果在 nested-name-specifier 之后指定的名称与标识符 simple-template-id 模板名称在最后一个组件中相同*嵌套名-specicifier,
  •     
         

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

         

[注意:...]

         

这样的构造函数名称只能用于命名构造函数的声明的 declarator-id using-declaration

         
         

88。忽略函数名称的查找包括出现在嵌套名称说明符中的名称, elaborated-type-specifier < / em>,或 base-specifier

  
  

14.6.1p2 本地声明的名称 [temp.local]

     
    

与普通(非模板)类一样,类模板具有注入类名     (第9条)。 inject-class-name可以用作模板名称或a     类型名称

         

当它与 template-argument-list 一起使用时,作为      template-argument 用于模板 template-parameter ,或作为最终版本     友元类模板的 elaborated-type-specifier 中的标识符     声明,它指的是类模板本身。

         

否则就是     相当于 template-name ,后跟 template-parameters     <>中包含的类模板。