I have the following C++ code:
//Define to 1 to make it work
#define WORKS 0
#if WORKS
template< typename T > struct Foo;
#else
template< typename T >
struct Foo {
T t;
};
#endif
class Bar; //Incomplete type
void fFooBar(Foo<Bar> const & foobar) { }
void f(Foo<Bar> const & foobar) {
fFooBar(foobar);
}
int main() {
return 0;
}
If WORKS is defined as 0 (the struct template is defined) the code doesn't compile, because it tries to instantiate it at fFooBar(foobar);
and fails, because Bar
is incomplete.
If WORKS is defined as 1 (the struct template is undefined) the code compiles.
According to the standard, a template should not be instatiated, unless a complete type is required (which is not the case for const&
) or it would alter the semantics of the code (which again isn't the case, and againt, the same should happen if the template was undefined).
Also, it's weird that the program can be made to compile by removing information from the compilation unit. But the fact that MSVC, gcc, and clang all do the same makes me think there must be a reason behind this.