You should add a forward declaration for build<int>()
to builder.h
, like so:
template<>
int Builder::build<int>();
Otherwise, while compiling main.cc
, the compiler sees only the generic template, and is allowed to inline an instance of the generic build()
function. If you add the forward declaration, the compiler knows you provided a specialization elsewhere, and will not inline it.
With -O3
, the compiler tries to inline, with -O0
it will not inline anything, hence the difference.
Your code actually violates the "One Definition Rule": it will create two definitions for Builder::build<int>()
, but they are not the same. The standard says the result is undefined, but no diagnostics are required. That is a bit unfortunate in this case, as it would have been helpful if a warning or error message was produced.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…