lexsintra
lexsintra

Reputation: 127

Missing type template parameter in function argument

Why does the following works?:

template<typename T> class example {
public:
    T val;
    example() {val=0;}
    example operator+(example ob) {
        example temp;
        temp.val = val+ob.val;
        return temp;
    }
};

int main() {
    example<int> a;
    a+a;
    return 0;
}

If I hadn't seen it compiling I would have said that the operator overload should had been as follows:

example<T> operator+(example<T> ob {
    example<T> temp;
    temp.val = val+ob.val;
    return temp;
}

Also, I tried to change the following in main:

example<int> a;

to:

example a;

but got an error saying "...missing template arguments..." My guess is that inside the class definition, compiler treats example as example. But as this is just a guess and I haven't been able to confirm it anywhere, thought I'd ask here.

Upvotes: 1

Views: 444

Answers (3)

Jesse Good
Jesse Good

Reputation: 52395

It's because of the injected-class-name (from 9p2):

A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.

and from 14.6.1p1:

Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class-name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

The injected-class-name refers to the example<T> inside the class itself allowing the shorthand version.

Upvotes: 2

jogojapan
jogojapan

Reputation: 70027

Yes, the template arguments can be omitted when you are inside the template definition (but, for example, not in main, because that is outside the template definition).

When omitted, the arguments will be replaced with the arguments of the current instantiation. I.e. when you instantiate the template as example<int>, all occurences of example without template argument inside the template definition will be replaced with example<int> for the purpose of that instantiation.

From the Standard (C++11, emphasis mine):

(14.6.2.1/1) A name refers to the current instantiation if it is

in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name (Clause 9) of the class template or nested class,
[...]

A few sections later, the Standard gives an example of this:

template <class T> class A {
  A*    p1;     // A is the current instantiation
  A<T>* p2;     // A<T> is the current instantiation

  /*...*/
};

Upvotes: 2

Karthik T
Karthik T

Reputation: 31972

If I understand your question correctly, Yes, within the class definition, you dont need to make each function a template of the class template parameter.

Indeed if you had to define the function outside the class it would need to be as below.

template<typename T>
example<T> example<T>::operator+(example<T> ob) {

p.s. you should change the arguement to const example<T>& ob to reduce unnecessary copies.

Upvotes: 1

Related Questions