I have written a C++ program which is bound using cmake and runs on a Debian machine. I am happy to say all known major bugs are corrected and I feel ready to bust it from
add_definitions(-Wall)
set(CMAKE_BUILD_TYPE Debug)
add_definitions("-O0 -std=c++0x")
all the way up to
add_definitions("-O2 -std=c++0x")
I did just that, and all of a sudden a templated class within my project (naively declared in some header file and defined for all use-cases in some separate .cpp) breaks with a load of "undefined" errors during linkage.
Some research on this very forum yielded threads like this one: Why can templates only be implemented in the header file? I believe I see what Luc in his celebrated answer is driving at: The compiler actually 'writes code' for each needed version of the templated class (i.e. T=int, T=float, T=what_ever_else) and for that purpose needs access to the actual implementation.
Fair enough. But what totally baffles me here: This apparently only is an issue when trying to optimize compilation. Using "-O0" all works fine. How can that be?
Appendix
1.) About the duplicate suspect: The question here is not what I have done that is wrong. My sin is clear: I defined templated functions out of reach of the header file which apparently is not allowed for reasons described above and within the post I already cited.
Given the truth of said cited posting it is obvious that my program cannot compile. What I do not understand is: Why does it compile with -O0.
2.) nos asked for some explicit errors. The ending of my last attempt using -O2 was still in my terminal buffer (sorry, compilation takes about an hour and thus is not easily reproduced). But as it is it breaks during linkage. Here goes what I still could lay my mouse pointer on:
/home/kochmn/projects/free_sentinel_gl/sentinel/src/game/game.cpp:432: undefined reference to `game::Board<game::Figure>::get(QPoint)'
libqt.a(game.cpp.o): In function `game::Game::hyperspace_jump()':
/home/kochmn/projects/free_sentinel_gl/sentinel/src/game/game.cpp:950: undefined reference to `game::Board<game::Square>::get(QPoint)'
[... many more like that all concerned about the templated class "Board"
which is declared in landscape.h, defined in landscape.cpp and
used pretty much everywhere else ... ]
collect2: error: ld returned 1 exit status
CMakeFiles/sentinel.dir/build.make:548: recipe for target 'sentinel' failed
make[2]: *** [sentinel] Error 1
CMakeFiles/Makefile2:127: recipe for target 'CMakeFiles/sentinel.dir/all' failed
make[1]: *** [CMakeFiles/sentinel.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2
3.) Concerning the comment question "How are the use-cases defined?": Let's take advantage of the fact that this is on GitHub.
All use-cases are defined here: https://github.com/kochsoft/free_sentinel_gl/blob/master/sentinel/src/game/landscape.cpp#L507 starting at line 507.
The header is here: https://github.com/kochsoft/free_sentinel_gl/blob/master/sentinel/src/include/landscape.h#L363 the pertinent passage starting at line 363.