Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct practice using 'using' in C++ templates

I have a small class that uses several STL lists internally

template<class T>
class MC_base {

  using OBJ_LIST  = std::list<T>;
  using OBJ_VAL   = typename OBJ_LIST::value_type;
  using OBJ_ITR   = typename OBJ_LIST::iterator;
  using OBJ_CITR  = typename OBJ_LIST::const_iterator;

  OBJ_LIST A,B,C;
  ...
};

With the using statements, if I write an iterator inside the class definition, it looks nice and clean:

OBJ_ITR begin() { return A.begin(); };
OBJ_ITR end()   { return A.end();   };
OBJ_CITR begin() const { return A.begin(); };
OBJ_CITR end()   const { return A.end();   };

Writing new functions, again inside the class definition, is easy since I can simply use the names OBJ_XXXX names when needed. Furthermore, if I decide to change the container type (to say std::vector) at some point later, I only have to change one line and as long as my new container supports all the same actions everything should be seamless.

This is problematic however when I want to define a new class function outside of the class definition

template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }

I'm not sure how to "bring out" the using statements so they work correctly with the templates and not to define them for every function which would be overly verbose. Also, I don't want to pollute the namespace with my using statements.

Is there a proper way to use using with templates?

like image 971
Hooked Avatar asked Dec 25 '22 21:12

Hooked


1 Answers

You can use a trailing return type. The type is looked up in the scope of the class, as with the parameter types, so nested types don't need qualification.

template<class T>
auto MC_base<T>::foo(OBJ_ITR x) -> OBJ_ITR { ... }
like image 59
Mike Seymour Avatar answered Jan 06 '23 21:01

Mike Seymour