Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not declared variable in default-constructed object in constructor

The above code doesn't work. Indeed the default constructed object f in the constructor of Foo complains that the value val is not declared in the scope. I don't understand why it is not declared.

struct Foo2
{
  Foo2(int val)
  {}
};

struct Foo
{
  Foo(int val, Foo2 f = Foo2(val))
  {}
};

int main()
{
  Foo f(1);
  return 0;
}
like image 706
Marco Agnese Avatar asked Apr 28 '15 16:04

Marco Agnese


People also ask

Can we use default arguments with constructor?

Like all functions, a constructor can have default arguments. They are used to initialize member objects. If default values are supplied, the trailing arguments can be omitted in the expression list of the constructor.

Does C++ always create a default constructor?

No, the C++ compiler doesn't create a default constructor when we initialize our own, the compiler by default creates a default constructor for every class; But, if we define our own constructor, the compiler doesn't create the default constructor.

What is default constructor argument?

Default constructor is used to initialize the values to the data members of an object. Default constructors have zero arguments or default parameters. They are created by the compiler when no constructors are declared explicitly inside the class.

How do you initialize a class in C++?

There are two ways to initialize a class object: Using a parenthesized expression list. The compiler calls the constructor of the class using this list as the constructor's argument list. Using a single initialization value and the = operator.


1 Answers

According to the C++ Standard (8.3.6 Default arguments):

9 Default arguments are evaluated each time the function is called. The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default argument, even if they are not evaluated. Parameters of a function declared before a default argument are in scope and can hide namespace and class member names.

In any C++ (not only C++ 2014) you can overload the constructor. For example

struct Foo
{
  Foo(int val )
  { Foo2 f(val); /*...*/ }
  Foo(int val, Foo2 f )
  {}
};

Or you can use a delegating constructor (if your compiler supports the new Standard)

struct Foo
{
  Foo(int val ) : Foo( val, Foo2( val ) )
  {}
  Foo(int val, Foo2 f )
  {}
};
like image 131
Vlad from Moscow Avatar answered Oct 20 '22 02:10

Vlad from Moscow