6

According to Why isn't argument deduction allowed in function return type?

When specifying a return type in a template class member function we have to be specific, for example: "the type std::vector isn't a type, std::vector<int> is."

So why do both of these examples compile? If I don't include the <T> in the first example, it shouldn't even be considered a type right?

template<typename T>
Queue<T>::Queue(const Queue& st) {}

template<typename T>
Queue<T>::Queue(const Queue<T>& st) {}

Given this template class

template<typename T>
class Queue {
   private:

    struct Node {
        Node (T value) : value(value), next(nullptr) {}
        Node (T value, Node* next) : value(value), next(next) {}
        T value;
        Node* next;
    };

    Node* head;
    size_t sz;
    void cleanList();

  public:
    Queue();

    Queue(const Queue& st);
    Queue& operator=(const Queue& st);

    ~Queue();

    size_t size() const noexcept;
    bool isEmpty() const noexcept;

    T& front();
    const Tt& front() const;

    void enqueue(const T& elem);

    void dequeue();
};
csguy
  • 1,354
  • 2
  • 17
  • 37
  • What is the declaration of `Queue`? – Code-Apprentice Jan 27 '20 at 22:10
  • @Code-Apprentice added – csguy Jan 27 '20 at 22:11
  • 1
    Look up [injected-class-name](https://en.cppreference.com/w/cpp/language/injected-class-name). – HolyBlackCat Jan 27 '20 at 22:11
  • When asking questions, please provide enough context so that there is no doubt what you are talking about, preferably in the form of a [repro]. One can guess that what you are showing here are out-of-class constructor definitions for some class template `Queue`, but something like this is not always obvious. – walnut Jan 28 '20 at 16:54

1 Answers1

8

The reason these examples work is because of the injected class name. When you have

template<typename T>
some_type<T> some_type<T>::some_func(some_type)

the return type is not in scope of the class so you need to provide the template parameter. In the function parameter you are in the scope of the class and in the scope of the class some_type is injected as a name for some_type<T> so you don't need to use some_type<T>.

walnut
  • 21,629
  • 4
  • 23
  • 59
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • whats the difference between a template name and a type name? I was reading https://en.cppreference.com/w/cpp/language/injected-class-name for reference – csguy Jan 27 '20 at 22:59
  • 1
    @csguy Using the first code block under *In class template* `X` is a template name because you are specifying which template of `X` you want. In `A`, `X` is also a template name because `A` has a template template so it requires you to pass a template to it. In `X* q;` now `X` is a type name because it is the injected name for `X` and since no `<>` were used it is considered a type, not a template in this case. – NathanOliver Jan 28 '20 at 13:15