I am revisiting C++ and have been following a tutorial with no real issues. However, I have got to a section on structs which says that in c++14 you can use both non-static initialisation and unifrom initialisation. As per:-
However, in C++14, this restriction was lifted and both can be used. If both are provided, the initializer list/uniform initialization syntax takes precedence. In the above example, Triangle x would be initialized with length and width 2.0.
The code I have is :-
struct Triangle
{
double length = 1.23; // non-static member initialization
double width = 2.45;
};
int Triangular()
{
Triangle x{ 2.0, 2.0 }; // uniform initialization
return 0;
}
......
int main() ......
However, I cannot get this to compile (I'm using Code::Blocks on Windows 7). If I remove the non-static initialisation and use (i.e remove the = 1.23
and = 2.45
) then it does compile:-
struct Triangle
{
double length; // non-static member initialization
double width;
};
int Triangular()
{
Triangle x{ 2.0, 2.0 }; // uniform initialization
return 0;
}
......
int main() ......
My first thought was that I don't have c++14. So I have followed Enabling -std=c++14
flag in Code::Blocks and I appear to have the compiler set to c++14 (one exception is that there was no make.exe
so the make program is mingw32-make.exe
(as per Settings/Compiler/Toolchain executables).
I have:- GNU GCC compiler
Compiler settings as :-
-std=c++14 compiler flags
-std=c++98 -std=c++0x -std=c++11 as the supercedes
Toolchain Executables as :-
gcc.exe C Compiler g++.exe C++ Compiler g++.exe Linker for dynamic libs ar.exe Linker for static libs GDB/CDB debugger : Default windres.exe Resource compiler mingw32-make.exe Make program
The Project Build options are all blank (So I assume the Code::Block settings are used.)
When I compile the failing code (the first code with the non-static initialisations) I get the following :-
Build Log
g++.exe -Wall -fexceptions -g -std=c++14 -c "D:\C++ Projects\gettingStarted\main.cpp" -o obj\Debug\main.o
D:\C++ Projects\gettingStarted\main.cpp: In function 'int Triangular()':
D:\C++ Projects\gettingStarted\main.cpp:24:22: error: no matching function for call to 'Triangle::Triangle(<brace-enclosed initializer list>)'
Triangle x{ 2.0, 2.0 }; // uniform initialization
^
D:\C++ Projects\gettingStarted\main.cpp:24:22: note: candidates are:
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle()
struct Triangle
^
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: candidate expects 0 arguments, 2 provided
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle(const Triangle&)
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: candidate expects 1 argument, 2 provided
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: constexpr Triangle::Triangle(Triangle&&)
D:\C++ Projects\gettingStarted\main.cpp:16:8: note: candidate expects 1 argument, 2 provided
Process terminated with status 1 (0 minute(s), 0 second(s))
1 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Using the second code (non-static initialisation removed) I just get a warning about x not being used (that's fine I can manage that) as per :-
Build Log
-------------- Build: Debug in gettingStarted (compiler: GNU GCC Compiler)---------------
g++.exe -Wall -fexceptions -g -std=c++14 -c "D:\C++ Projects\gettingStarted\main.cpp" -o obj\Debug\main.o
D:\C++ Projects\gettingStarted\main.cpp: In function 'int Triangular()':
D:\C++ Projects\gettingStarted\main.cpp:24:10: warning: unused variable 'x' [-Wunused-variable]
Triangle x{ 2.0, 2.0 }; // uniform initialization
^
g++.exe -o bin\Debug\gettingStarted.exe obj\Debug\main.o obj\Debug\myotherfile.o
Output file is bin\Debug\gettingStarted.exe with size 1.07 MB
Process terminated with status 0 (0 minute(s), 1 second(s))
0 error(s), 1 warning(s) (0 minute(s), 1 second(s))
So I believe that I'm either using invalid code or that I am not compiling using c++14 but rather c++11. Is the issue one of these, or perhaps something else?
Triangle x{ 2.0, 2.0 };
The line above is attempting to perform aggregate initialization of Triangle
. However, in C++11, the presence of non-static data member initializers, or default member initializers as they're now known as, prevented Triangle
from being an aggregate, and the initialization would fail.
This rule was modified in C++14, and aggregates are now allowed to have default member initializers. It seems your compiler doesn't yet support that. Your example does compile on a conforming C++14 compiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With