Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is it required to add the types for template code and when not?

Tags:

c++

templates

I stumbled upon the fact that in C++ for the code

template<std::signed_integral T>
struct Ratio
{
    T Nominator; T Denominator;
    Ratio& operator+=(const Ratio& R);
    ...
};
template<std::signed_integral T>
Ratio<T>& Ratio<T>::operator+=(const Ratio& R)
{
  ...
}

the template parameter seems to be required to be repeated for the struct name in the return type and before the ::, but not for the parameter. Is there a clearcut rule for this? Why does the compiler assume, that the parameters are as defined in the introducing "template" line but it cannot or does not want to for the return type or the class name?

like image 509
Gregor Grunz Avatar asked Jan 23 '26 16:01

Gregor Grunz


1 Answers

Classes (which includes structs) have something called injected-class-name in them, which acts as a (somewhat magical) typedef pointing to the class itself:

template<std::signed_integral T>
struct Ratio
{
    using Ratio = Ratio<T>; // Pretend it works like this.
    // ...
};

This is what lets you omit template arguments. It only works inside of the scope of this class.

In Ratio<T>& Ratio<T>::operator+=(const Ratio& R), we only know that we're inside of the class after we see Ratio<T>::, so that's when the injected-class-name becomes visible, and when the template arguments become optional.

The trailing return type can help with this: auto Ratio<T>::operator+=(const Ratio& R) -> Ratio.

like image 156
HolyBlackCat Avatar answered Jan 25 '26 05:01

HolyBlackCat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!