2

Sorry that I'm a beginner of c++ programming.

As I know, the type arguments in template declaration can be omitted. For example

template<typename T>
class A{
A<T> func(A<T> t);
}

can be written as

template<typename T>
class A{
A func(A t) {}
}

Also, I know that if the member functions are defined outside of the class, the type arguments cannot be omitted. However, I found that the type argument in the function's argument type can be omitted as well. Why is it like this?

I mean for

A<T> A<T>:: func(A<T> t) {}

why the code below is permissible even though it's outside the template declaration?

A<T> A<T>:: func(A t) {}
dnjsdnwja
  • 389
  • 1
  • 7
  • 17
  • The "duplicate" does not answer this question. OP is aware that the injected classname exists, the question is why it works outside the class' body. – Quentin Oct 27 '17 at 16:02
  • Oh sorry those should be A A:: func(A t) {} and A A:: func(A t) {} – dnjsdnwja Oct 27 '17 at 16:05
  • Approximately, the compiler reads code from left to right. When it sees `A::`, it knows that we are inside `A` again, so it can assume that an `A` without parameters really means `A`. – Daniel H Oct 27 '17 at 16:06

1 Answers1

2

The reason this works is because A<T>:: scopes the declaration -- everything that follows it knows about the contents of A<T>, including the injected classname A. This is also strictly in source code order, leading to the following curiosity between two semantically identical definitions:

A A<T>::func(A t) {} // Doesn't work -- `A` is not known before `A<T>::`

auto A<T>::func(A t) -> A {} // Works, because the return type is after `A<T>::`!
Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Which, IIRC, was a big reason for the introduction of the `auto f(args) -> type` syntax. – Daniel H Oct 27 '17 at 16:07
  • @DanielH It's also much appreciated when you want to use the parameters in the return type, e.g. `template auto f(T a, U b) -> decltype(a + b)`. – Quentin Oct 27 '17 at 16:11
  • I was considering that as part of the same reason, but an example of where it’s more useful. Doing this puts the return type at a point where more things are in scope, so you can just use `A` or `decltype(a + b)` instead of `A` or `decltype(declval() + declval())`. – Daniel H Oct 27 '17 at 16:36