我有一个在内部使用多个STL列表的小类
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;
...
};
使用using
语句,如果我在类定义中编写一个迭代器,它看起来很干净:
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(); };
再次在类定义中编写新函数很容易,因为我可以在需要时简单地使用名称OBJ_XXXX
。此外,如果我决定稍后更改容器类型(比如std::vector
),我只需更改一行,只要我的新容器支持所有相同的操作,一切都应该是无缝的。
但是当我想在类定义
之外定义一个新的类函数时,这是有问题的template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }
我不确定如何“带出”using语句,以便它们能够正确使用模板,而不是为每个函数定义它们,这些过于冗长。另外,我不想用using语句污染命名空间。
是否有正确的方法将using
与模板一起使用?
答案 0 :(得分:5)
在课外,您需要对名称进行限定。您还需要使用typename
关键字向编译器承诺这些名称是每个特化中的类型。
template<class T>
typename MC_base<T>::OBJ_ITR MC_base<T>::foo( typename MC_base<T>::OBJ_ITR x ) { ... }
9.3p2要求
出现在类定义之外的成员函数定义 在包含类定义的命名空间范围内。
这会阻止对存在这些名称的定义使用更嵌套的作用域。更不用说这些名称取决于模板参数的问题了。
最好的解决方案可能是内联编写这些函数。这些是模板类的成员,因此无论如何它们都必须包含在头文件中。
答案 1 :(得分:5)
您可以使用尾随返回类型。类型在类的范围内查找,与参数类型一样,因此嵌套类型不需要限定。
template<class T>
auto MC_base<T>::foo(OBJ_ITR x) -> OBJ_ITR { ... }