在C++模板中使用'using'进行正确练习

Hoo*_*ked 4 c++ templates using c++11

我有一个小类,内部使用几个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;
  ...
};
Run Code Online (Sandbox Code Playgroud)

使用这些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();   };
Run Code Online (Sandbox Code Playgroud)

在类定义中再次编写新函数很容易,因为我可以OBJ_XXXX在需要时简单地使用名称.此外,如果我决定std::vector稍后更改容器类型(比方说),我只需更改一行,只要我的新容器支持所有相同的操作,一切都应该是无缝的.

但是,当我想在类定义之外定义一个新的类函数时,这是有问题的

template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }
Run Code Online (Sandbox Code Playgroud)

我不确定如何"带出"using语句,以便它们与模板一起正确工作,而不是为每个过于冗长的函数定义它们.另外,我不想用using语句污染命名空间.

有没有正确的方法using与模板一起使用?

Ben*_*igt 5

在课外,您需要对名称进行限定.您还需要使用typename关键字来向编译器承诺这些名称是每个特化中的类型.

template<class T>
typename MC_base<T>::OBJ_ITR MC_base<T>::foo( typename MC_base<T>::OBJ_ITR x ) { ... }
Run Code Online (Sandbox Code Playgroud)

9.3p2要求

出现在类定义之外的成员函数定义应出现在包含类定义的命名空间范围内.

这会阻止使用更嵌套的范围来定义这些名称的定义.更不用说这些名称依赖于模板参数的问题.


最好的解决方案可能就是内联编写这些函数.这些是模板类的成员,因此无论如何它们必须包含在头文件中.


Mik*_*our 5

您可以使用尾随返回类型.在类的范围内查找类型,与参数类型一样,因此嵌套类型不需要限定.

template<class T>
auto MC_base<T>::foo(OBJ_ITR x) -> OBJ_ITR { ... }
Run Code Online (Sandbox Code Playgroud)