Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing class member vector with size fails

I'm new with c++ and came across to this problem. Here is my code:

class A
{
    std::vector <int> vec(10);
};

It gives me error saying expected a type specifier. I know that this way of initializing a vector is not acceptable and it should be done in constructor but I'm curious why this fails. I also noticed that this:

class A
{
    std::vector <int> vec = std::vector<int>(10);
};

Works perfectly fine.

So my question is why does second case work even though we are still creating vector with "predefined size"(std::vector<int>(10)), and why does the first case fail? thanks.

P.S I'm trying to create vector with size for 10 ints, not create a vector with with 10 already inserted in it.

like image 909
user3503143 Avatar asked Feb 08 '19 10:02

user3503143


1 Answers

What?

Since C++11 we have non-static data member initialisers, making this approach to initialising members completely valid. However, you must use either = or {}.

Formally, if an initializer is present here, it must be with a brace-or-equal-initializer grammatical production.

Since you've instead used a syntax that doesn't count as initialisation here, the compiler tries to make a function declaration out of vec, which breaks because 20 is not a type.


Why?

The chapter named "Problem 1" in the original feature proposal (N2756) explains that () was disallowed here to avoid some confusion with respect to member function declarations.

The author does note therein that the committee could have let it be, and had it work like other declarations — that is, it's a function if it can be, and an object otherwise*. But the author decided to go a different direction and just ban the syntax to avoid the problem in this particular case.

Unfortunately, this makes initializers of the “( expression-list )” form ambiguous at the time that the declaration is being parsed [..]

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 [..]

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; and we can use “typename” if we really mean a type [..]

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).

The solution proposed in this paper is to allow only initializers of the “= initializer-clause” and “{ initializer-list }” forms. That solves the ambiguity problem in most cases.

Such is life.


So?

I'm trying to create vector with size for 10 ints, not create a vector with with 10 already inserted in it.

This is an important point. Be careful, because initialising a vector with {} won't do that. "Uniform" initialisation unfortunately merely added more meanings. So much for solving the ambiguity problem…

You should therefore use either the = syntax, or just do this in the constructor (my favourite).


* This is where the most vexing parse can sometimes bite you, though not every occurrence of unintended function declarations is an example of the most vexing parse.

like image 181
Lightness Races in Orbit Avatar answered Sep 19 '22 22:09

Lightness Races in Orbit