为什么使用基本类型作为 base-class 有时会编译?
Why does using a fundamental type as a base-class compile sometimes?
此编译(使用 GCC 9 和 Clang 9 测试):
template<typename U>
struct inherit : U { };
int test(inherit<int> arg);
但这不是:
int test(inherit<int> arg) { }
为什么第一个编译通过?
int test(inherit<int> arg);
只是一个声明。因此,我们还不需要知道 inherit<int>
。因此,编译器将放手。
有了 int test(inherit<int> arg) { }
你现在有了一个定义,现在我们需要知道 inherit<int>
所以 arg
可以在函数退出时销毁。那时模板被实例化,你得到一个错误,因为它是无效的。
忽略该声明的另一个原因是 inherit
稍后可以针对 int
进行专门化,并且该专门化实际上可能是有效的 class,因为您可以拥有类似
template<>
struct inherit<int> { };
如果您要在 int test(inherit<int> arg);
和 int test(inherit<int> arg) { }
之间添加它,那么代码现在可以编译,因为 inherit<int>
现在是一个有效类型。
我希望其他人能解释一下原因。我将在这里使用现象学方法 ;)。
一旦你实际实例化一个 inherit<int>
:
,你的第一个版本也无法编译
int main() {
test( inherit<int>{} );
}
错误:
prog.cc: In instantiation of 'struct inherit<int>':
prog.cc:9:24: required from here
prog.cc:4:8: error: base type 'int' fails to be a struct or class type
4 | struct inherit : U { };
| ^~~~~~~
我本可以简单地尝试创建一个 inherit<int>
对象(而不调用 test
)来得到类似的错误。
另一方面,这只是一个声明:int test(inherit<int> arg);
所以在实际提供定义之前,可以对 inherit
进行专门化,使我们也能够为 [= 提供有效的定义15=]:
template<typename U>
struct inherit : U { };
// looks broken
int test(inherit<int> arg);
// but that this point we dont really know yet what `inherit<int>` really is
// whoops inherit<int> is something different now
template <> struct inherit<int> {};
// ... and now this is completely fine
int test(inherit<int> arg) {}
int main() {
test( inherit<int>{} );
}
此编译(使用 GCC 9 和 Clang 9 测试):
template<typename U>
struct inherit : U { };
int test(inherit<int> arg);
但这不是:
int test(inherit<int> arg) { }
为什么第一个编译通过?
int test(inherit<int> arg);
只是一个声明。因此,我们还不需要知道 inherit<int>
。因此,编译器将放手。
有了 int test(inherit<int> arg) { }
你现在有了一个定义,现在我们需要知道 inherit<int>
所以 arg
可以在函数退出时销毁。那时模板被实例化,你得到一个错误,因为它是无效的。
忽略该声明的另一个原因是 inherit
稍后可以针对 int
进行专门化,并且该专门化实际上可能是有效的 class,因为您可以拥有类似
template<>
struct inherit<int> { };
如果您要在 int test(inherit<int> arg);
和 int test(inherit<int> arg) { }
之间添加它,那么代码现在可以编译,因为 inherit<int>
现在是一个有效类型。
我希望其他人能解释一下原因。我将在这里使用现象学方法 ;)。
一旦你实际实例化一个 inherit<int>
:
int main() {
test( inherit<int>{} );
}
错误:
prog.cc: In instantiation of 'struct inherit<int>':
prog.cc:9:24: required from here
prog.cc:4:8: error: base type 'int' fails to be a struct or class type
4 | struct inherit : U { };
| ^~~~~~~
我本可以简单地尝试创建一个 inherit<int>
对象(而不调用 test
)来得到类似的错误。
另一方面,这只是一个声明:int test(inherit<int> arg);
所以在实际提供定义之前,可以对 inherit
进行专门化,使我们也能够为 [= 提供有效的定义15=]:
template<typename U>
struct inherit : U { };
// looks broken
int test(inherit<int> arg);
// but that this point we dont really know yet what `inherit<int>` really is
// whoops inherit<int> is something different now
template <> struct inherit<int> {};
// ... and now this is completely fine
int test(inherit<int> arg) {}
int main() {
test( inherit<int>{} );
}