简体   繁体   English

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

[英]c++ template class, initialization () vs {}

I am wondering why I can't initialize an instance of the following template class with () instead of {} within the scope of another class (C++ 11)? 我想知道为什么我不能在另一个类(C ++ 11)的范围内用()而不是{}初始化以下模板类的实例? error: expected identifier before numeric constant 错误:数字常量之前的预期标识符

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;
}

That's simply a restriction on how class members can be initialised. 这只是对如何初始化班级成员的限制。 You can use {} or = but not () . 您可以使用{}=但不能使用()

I don't think there's a particularly compelling justification for the restriction; 我认为限制没有特别令人信服的理由; it's just one of the language's many quirks. 这只是语言中很多怪癖之一。

Initializers using () were disallowed in the proposal of non-static data member initializers - N2756 , for the reasons mentioned by @TC in the comment section: 由于@TC在评论部分中提到的原因, 在非静态数据成员初始化程序-N2756提议中不允许使用() 初始化程序

Unfortunately, this makes initializers of the “ ( expression-list ) ” form ambiguous at the time that the declaration is being parsed: 不幸的是,这使得“ ( 表达式列表 ) ”的初始化器在解析声明时形式不明确:

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

One possible solution is to rely on the existing rule that, if a declaration could be an object or a function, then it's a function: 一种可能的解决方案是依赖现有规则,如果声明可以是对象或函数,那么它是一个函数:

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

A similar solution would be to apply another existing rule, currently used only in templates, that if T could be a type or something else, then it's something else; 一个类似的解决方案是应用另一个现有的规则,目前只在模板中使用,如果T可以是一个类型或其他东西,那么它就是其他东西; and we can use “typename” if we really mean a type: 如果我们真的是一个类型,我们可以使用“typename”:

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

Both of those solutions introduce subtleties that are likely to be misunderstood by many users (as evidenced by the many questions on comp.lang.c++ about why “ int i(); ” at block scope doesn't declare a default-initialized int ). 这两种解决方案都引入了很多可能被许多用户误解的细微问题(comp.lang.c ++上的许多问题都证明了为什么“ int i(); ”在块范围内没有声明默认初始化的int ) 。 The solution proposed in this paper is to allow only initializers of the “ = initializer-clause ” and “ { initializer-list } ” forms. 本文提出的解决方案是仅允许“ = initializer-clause ”和“ { initializer-list } ”形式的初始化器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM