Reputation: 88168
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?
Upvotes: 4
Views: 300
Reputation: 254501
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 { ... }
Upvotes: 5
Reputation: 283684
Outside the class, you need to qualify the names. You additionally need to use the typename
keyword to promise the compiler that those names are types in every specialization.
template<class T>
typename MC_base<T>::OBJ_ITR MC_base<T>::foo( typename MC_base<T>::OBJ_ITR x ) { ... }
9.3p2 requires that
A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.
Which prevents using a more nested scope for the definition where these names would be present. Not to mention the problem that those names depend on the template parameter.
The best solution is probably to write those functions inline. These are members of a template class, so they have to be included in the header file anyway.
Upvotes: 5