c++ primer says :
The default constructor is used automatically whenever an object is default or value initialized.
Default initialization happens
• When we define nonstatic variables (§ 2.2.1, p. 43) or arrays (§ 3.5.1, p. 114) at block scope without initializers
• When a class that itself has members of class type uses the synthesized de- fault constructor (§ 7.1.4, p. 262)
• When members of class type are not explicitly initialized in a constructor initializer list (§ 7.1.4, p. 265)
Value initialization happens
• During array initialization when we provide fewer initializers than the size of the array (§ 3.5.1, p. 114)
• When we define a local static object without an initializer (§ 6.1.1, p. 205) • When we explicitly request value initialization by writing an expressions of the form T() where T is the name of a type (The vector constructor that takes a single argument to specify the vector’s size (§ 3.3.1, p. 98) uses an argument of this kind to value initialize its element initializer.)
Classes must have a default constructor in order to be used in these contexts. Most of these contexts should be fairly obvious
class foo{
public :
int data;
foo() = default;
};
int main(){
std::vector<foo> fvec1;
std::vector<foo> fvec2(4,foo(2));
foo f[5]{1,2,4};
std::cout << fvec2[1].data << " " << f[4].data << std::endl;
}
Output :
error: no matching function for call to ‘foo::foo(int)’
std::vector<foo> fvec2(4, foo(2));
^
error: could not convert ‘1’ from ‘int’ to ‘foo’
foo f[5]{1,2,4};
^
But if we remove the following line
foo() = default;
the code works, while synthesised default constructor is used, why not a default constructor declared as default, why I am not getting the default behaviour though declared default.
And if possible can any one provide examples for above reasons said by 'c++ primer', because it is so confusing.
standard : c++ 20
compiler : g++-12, clang++-15
So we have a couple of things going on here. First is that
foo
in the form ofis an aggregate. An aggregate can be initialized with
{}
and beginning in C++20 that was expanded to include()
for initialization as well. That means inthat you aggregate initialize the objects.
When you change
foo
toYou no longer have an aggregate because you have a user declared constructor. This means that to value initialize it you need to provide a constructor that takes in the value(s) that are needed to construct the class. You do that by adding a constructor like