我有以下C++代码:
//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;
}
Run Code Online (Sandbox Code Playgroud)
如果WORKS被定义为0(定义了结构模板),则代码不会编译,因为它尝试将其实例化fFooBar(foobar);并失败,因为它Bar是不完整的.
如果WORKS定义为1(结构模板未定义),则代码将编译.
根据标准,模板不应该被实例化,除非需要一个完整的类型(事实并非如此const&)或者它会改变代码的语义(事实并非如此),同样,应该如果模板未定义则发生).
而且,通过从编译单元中删除信息可以使程序编译,这很奇怪.但MSVC,gcc和clang都这样做的事实让我觉得必须有这背后的原因.