C ++ template class, initialization () vs {}
I'm wondering why I can't initialize an instance of the following template class with () instead of {} within the scope of another class (C ++ 11)? error: expected id 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;
}
source to share
Using initializers ()
were disallowed in the non-static member initializer clause - N2756 , for the reason mentioned by @TC in the comment section:
Unfortunately, this makes the "
(
list-list)
" initializers form ambiguous at the time of parsing the declaration:
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 an existing rule that if a declaration can be an object or a function, then its function is:
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, which is currently only used in templates, if T can be a type or something else, then different; and we can use "typename" if we really mean the type:
struct S { int i(x); // unabmiguously a data member int j(typename y); // unabmiguously a member function };
Both of these solutions introduce subtleties that many users might misunderstand (as evidenced by many of the comp.lang.C ++ questions about why "
int i();
" in block scope doesn't declare default-initializedint
). The solution suggested in this article is to only allow "=
initializer-clause" and "{
initializer-list}
" form initializers .
source to share