Я надеюсь, что кто-то еще объяснит почему. Я буду использовать феноменологический подход здесь;).
Ваша первая версия также не будет скомпилирована, когда вы на самом деле создадите 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
, что позволяет нам также предоставить действительное определение для test
:
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>{} );
}