Now we have five forms of initializations. They are
T x = expression;
T x = ( expression );
T x ( expression );
T x = { expression };
T x { expression };
Each of the forms has its own peculirities. :)
For example let's assume that you have the following declarations in the global namespace
int x;
void f( int x ) { ::x = x; }
int g() { return x ; }
long h() { return x; }
then in main you can write
int main()
{
int x ( g() );
}
This code will compile successfully.
However a programmer by mistake made a typo
int main()
{
int x; ( g() );
^^
}
Oops! This code also compiles successfully.:)
But if the programmer would write
int main()
{
int x = ( g() );
}
and then make a typo
int main()
{
int x; = ( g() );
^^
}
then in this case the code will not compile.
Well let's assume that the programmer decided at first to set a new value for the global variable x before initializing the local variable.
So he wrote
int main()
{
int x ( f( 10 ), g() );
}
But this code does not compile!
Let's insert equality sign
int main()
{
int x = ( f( 10 ), g() );
}
Now the code compiles successfully!
And what about braces?
Neither this code
int main()
{
int x { f( 10 ), g() };
}
nor this code
int main()
{
int x = { f( 10 ), g() };
}
compiles!:)
Now the programmer decided to use function h(), He wrote
int main()
{
int x ( h() );
}
and his code compiles successfully. But after a time he decided to use braces
int main()
{
int x { h() };
}
Oops! His compiler issues an error
error: non-constant-expression cannot be narrowed from type 'long' to
'int' in initializer list
The program decided to use type specifier auto. He tried two approaches
int main()
{
auto x { 10 };
x = 20;
}
and
int main()
{
auto x = { 10 };
x = 20;
}
and ...some compilers compiled the first program but did not compile the second program and some compilers did not compile the both programs.:)
And what about using decltype
?
For example the programmer wrote
int main()
{
int a[] = { 1, 2 };
decltype( auto ) b = a;
}
And his compiler issued an error!
But when the programmer enclosed a in parentheses like this
int main()
{
int a[] = { 1, 2 };
decltype( auto ) b = ( a );
}
the code compiled successfully!:)
Now the programmer decided to learn OOP. He wrote a simple class
struct Int
{
Int( int x = 0 ) : x( x ) {}
int x;
};
int main()
{
Int x = { 10 };
}
and his code compiles successfully.
But the programmer has known that there is function specifier explicit
and he has decided to use it
struct Int
{
explicit Int( int x = 0 ) : x( x ) {}
int x;
};
int main()
{
Int x = { 10 };
}
Oops! His compiler issued an error
error: chosen constructor is explicit in copy-initialization
The programmer decided to remove the assignment sign
struct Int
{
explicit Int( int x = 0 ) : x( x ) {}
int x;
};
int main()
{
Int x { 10 };
}
and his code compiled successfully!:)