简体   繁体   中英

What does this “<>” mean inside a template class function?

There is a code like this.

const std::string DeviceTypeStrings[] ={ "A", "B", "C", "D", "E" };

enum DeviceTypes { A = 0, B, C, D, E };

template <DeviceTypes T> class DeviceType;
template <DeviceTypes T> std::ostream& operator<< (std::ostream& output, const DeviceType<T>& dev);

template <DeviceTypes T> class DeviceType {
    public:
         static const int value = T;
         static const std::string string;
         friend std::ostream & operator<< <>(std::ostream & output, const DeviceType<T> & deviceType );
};
template <DeviceTypes T> const std::string DeviceType<T>::string = DeviceTypeStrings[T];
template <DeviceTypes T> std::ostream & operator<< (std::ostream & output, const DeviceType<T> & deviceType ){
    if ( DeviceType<T>::string.find(' ') != std::string::npos ){
        return output << "\"" << DeviceType<T>::string << "\""; 
    } else {
        return output << DeviceType<T>::string;
    }   
}

int main () {
    DeviceType<A> myType;
    std::cout << myType << std::endl;
    return 0;    
}

Note there is a "<>" after the operator<< inside class DeviceType, what does "<>" mean? If you could, why does it has to be there?

It simply means that the friend declaration refers to a particular specialization of function template operator << (declared previously), not to some yet undeclared ordinary non-template function operator << .

Which specialization this friend declaration refers to is determined by the argument deduction mechanism, ie the actual template arguments are implicitly derived from the parameter types used in friend declaration. For this reason there's no need to specify template arguments in <> explicitly, but an empty pair of <> is still required.

In other words, the author of the code could've stated explicitly

friend std::ostream & operator<< <T>(std::ostream & output, 
                                     const DeviceType<T> & deviceType );

(note the explicit T in <T> ). However, since the compiler can figure it out by itself (derive it from the type of the second argument), it is perefectly possible to put just an empty pair of <> there.

Now, if the code just said

friend std::ostream & operator<<(std::ostream & output, 
                                 const DeviceType<T> & deviceType );

(ie no <> at all), it would befriend an ordinary (non-template) function operator << , which is not what the author wanted.

Overload resolution feature that works in this friend declaration can be illustrated without any friend declarations by the following simple example

void foo(int);
template <typename T> void foo(T);

int main() {
  foo(42);      // calls non-template function
  foo<int>(42); // calls template function, explicit template argument given
  foo<>(42);    // calls template function, template argument deduced by compiler
}

When you want to tell the compiler that you specifically want to refer to a template version of the function, you have to include triangular brackets into the reference, even if there's nothing between them.

The compiler checks for < after operator<< if it's a friend function of a template class. It's considered as the template argument list.

It is same like at this link . See the "Template specialization" chapter.

// template specialization
#include <iostream>
using namespace std;

// class template:
template <class T>
class mycontainer {
    T element;
  public:
    mycontainer (T arg) {element=arg;}
    T increase () {return ++element;}
};

// class template specialization:
template <>
class mycontainer <char> {
    char element;
  public:
    mycontainer (char arg) {element=arg;}
    char uppercase ()
    {
      if ((element>='a')&&(element<='z'))
      element+='A'-'a';
      return element;
    }
};

int main () {
  mycontainer<int> myint (7);
  mycontainer<char> mychar ('j');
  cout << myint.increase() << endl;
  cout << mychar.uppercase() << endl;
  return 0;
}

It's just how you refer to already defined template object (or function).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM