An undeclared variable in the default object in the constructor

The code above does not work. Indeed, the default constructed object f in the Foo constructor complains that the value of val not declared in the scope. I do not understand why it is not announced.

 struct Foo2 { Foo2(int val) {} }; struct Foo { Foo(int val, Foo2 f = Foo2(val)) {} }; int main() { Foo f(1); return 0; } 
+6
source share
4 answers

According to the C ++ standard (8.3.6 default arguments):

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

In any C ++ (not just C ++ 2014) you can overload the constructor. for instance

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

Or you can use the delegation constructor (if your compiler supports the new standard)

 struct Foo { Foo(int val ) : Foo( val, Foo2( val ) ) {} Foo(int val, Foo2 f ) {} }; 
+5
source

This is how the language works; the default arguments cannot depend on other parameters, since the order of their initialization remains unspecified.

In C ++ 11 or later, you can get around this with overload:

 Foo(int val) : Foo(val, Foo2(val)) {} 
+2
source
 struct Foo2 { int x; Foo2(int val): x(val) {} }; struct Foo { int y; Foo2 f2; Foo(int val, Foo2 f): y(val), f2(f) {} Foo(int val): y(val), f2(val) {} }; int main() { Foo f(1); } 
0
source

You can use templates to solve this problem:

 struct Foo2 { Foo2(int val) {} }; template <int val> struct Foo { Foo(Foo2 f = Foo2(val)) {} }; int main() { Foo<1> f = Foo<1>(); return 0; } 
0
source

Source: https://habr.com/ru/post/986166/


All Articles