c ++模板类,initialization()vs {}

时间:2015-05-12 16:37:24

标签: c++ templates c++11

我想知道为什么我无法在另一个类的范围内使用()而不是 {} 初始化以下模板类的实例(C ++ 11)?错误:数字常量之前的预期标识符

template <typename T>
class vec3 {

private:

    T   data[3];

public:

    vec3 (T a, T b, T c);
};

template <typename T> 
vec3<T>::vec3 (T a, T b, T c) 
{
    data[0] = a;
    data[1] = b;
    data[2] = c;
}

class whatever {

    vec3 <float> a (1,2,3); // not ok
    vec3 <float> b {1,2,3}; // ok

};

int main () {

    vec3 <float> a (1,2,3); // ok

    return 0;
}

2 个答案:

答案 0 :(得分:4)

这只是对如何初始化班级成员的限制。您可以使用{}=,但不能使用()

我认为限制没有特别令人信服的理由;这只是该语言的许多怪癖之一。

答案 1 :(得分:4)

由于@ T.C提到的原因,<{3}}中不允许使用()的初始化程序。在评论部分:

  

不幸的是,这会使“( 表达式列表 )的初始值设定项”   在解析声明时表单不明确:

struct S {
    int i(x); // data member with initializer
    // ...
    static int x;
};

struct T {
    int i(x); // member function declaration
    // ...
    typedef int x;
};
     

一种可能的解决方案是依赖现有规则,如果声明可以是对象或函数,那么它就是一个函数:

struct S {
    int i(j); // ill-formed...parsed as a member function,
              // type j looked up but not found
    // ...
    static int j;
};
     

类似的解决方案是应用另一个现有规则,目前仅在模板中使用,如果T可以是类型或   别的东西,那就是别的东西;我们可以使用“typename”if   我们的意思是一种类型:

struct S {
    int i(x); // unabmiguously a data member
    int j(typename y); // unabmiguously a member function
};
     

这两种解决方案都引入了很多可能被许多用户误解的微妙之处(正如许多问题所证明的那样)   comp.lang.c ++关于为什么“int i();”在块作用域中没有声明a   default-initialized int)。本文中提出的解决方案是仅允许“= 初始化子句”和“{ 初始化列表 {{1}的初始值设定项“表格。