This compiles (tested with GCC 9 and Clang 9):
template<typename U>
struct inherit : U { };
int test(inherit<int> arg);
But this does not:
int test(inherit<int> arg) { }
Why does the first one compile?
int test(inherit<int> arg);
is just a declaration. As such, we don't need to know about inherit<int>
yet. Because of that, the compiler will let it go.
With int test(inherit<int> arg) { }
you now have a definition and now we need to know about inherit<int>
so arg
can be destroyed when the function exits. At that point the template is instantiated and you get an error because it is invalid.
Another reason to ignore the declaration is that inherit
could later on get specialized for int
and that specialization might actually be a valid class since you could have something like
template<>
struct inherit<int> { };
If you were to add that between int test(inherit<int> arg);
and int test(inherit<int> arg) { }
then the code would now compile since inherit<int>
is now a valid type.
I hope someone else will explain the why. I will use a phenomenological approach here ;).
Your first version also fails to compile once you actually instantiate a inherit<int>
:
int main() {
test( inherit<int>{} );
}
Error:
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 { };
| ^~~~~~~
I could have simply tried to create a inherit<int>
object (without calling test
) to get similar error.
On the other hand, this is just a declaration: int test(inherit<int> arg);
so before actually providing the definition there could be a specialization for inherit
that enables us to also provide a valid definition for 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>{} );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With