Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 正确使用';使用';在C++;模板_C++_Templates_C++11_Using - Fatal编程技术网

C++ 正确使用';使用';在C++;模板

C++ 正确使用';使用';在C++;模板,c++,templates,c++11,using,C++,Templates,C++11,Using,我有一个小类,它在内部使用几个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_ite

我有一个小类,它在内部使用几个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;
  ...
};
同样在类定义中编写新函数很容易,因为我可以在需要时简单地使用名称
OBJ_XXXX
名称。此外,如果我以后决定更改容器类型(比如说
std::vector
),我只需要更改一行,只要我的新容器支持所有相同的操作,一切都应该是无缝的

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

template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }
模板
OBJ_ITR MC_base::foo(OBJ_ITR x){…}
我不知道如何“显示”using语句,使它们能够正确使用模板,而不是为每个过于冗长的函数定义它们。另外,我不想用using语句污染名称空间


有没有合适的方法可以将
与模板一起使用?

在类外,您需要限定名称。此外,还需要使用
typename
关键字向编译器保证,这些名称在每个专门化中都是类型

template<class T>
typename MC_base<T>::OBJ_ITR MC_base<T>::foo( typename MC_base<T>::OBJ_ITR x ) { ... }
模板
typename MC_base::OBJ_ITR MC_base::foo(typename MC_base::OBJ_ITR x){…}

9.3p2要求

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

这将阻止对这些名称所在的定义使用更嵌套的范围。更不用说那些名称依赖于模板参数的问题了



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

您可以使用尾随返回类型。与参数类型一样,该类型在类的作用域中查找,因此嵌套类型不需要限定

template<class T>
auto MC_base<T>::foo(OBJ_ITR x) -> OBJ_ITR { ... }
模板
自动MC_base::foo(OBJ_ITR x)->OBJ_ITR{…}

现在存在一种语法,可以在作用域为类时延迟函数返回类型,它类似于
模板自动Myclass::Func(arg)->NestedClassTypeFromMyClass{/…
@Hooked@BenVoigt参数类型不需要整个typename限定项,因为我们已经在类的作用域中。使用尾部返回类型可以得到更短的:
模板auto MC_base::foo(OBJ_ITR x)->OBJ_ITR{…}
@gx_u。这是一个很好的使用
auto
的方法。为了子孙后代着想,你能把它放在它自己的答案中吗?@Hooked我真的希望Ben Voigt会在他的答案中添加这个选项,但似乎Mike Seymour在我看到你的答案之前就把它作为自己的答案发布了。@gx_u。在我的世界里,我们称之为被挖走。或者嗯,你通过Mike S.给出的答案似乎更像是C++11,所以我将把答案改为他的。不过,这个答案中的信息对于理解问题Ben!+1非常有价值。我也考虑了Ben答案中的解决方案,但这通常要简洁得多。不过,这都已经在gx的评论中了。。。(因为我在那里发表了评论)Live example@gx\对不起,我没有注意到你已经在评论中给出了答案;我只是在添加我的答案之前阅读了另一个答案。问题:如果在声明中没有使用尾随返回类型,那么可以在定义中使用它吗?@BenVoigt:我没有想到。在我尝试时它是有效的,不允许它似乎很愚蠢,但当然这样做了不一定意味着这是允许的。
template<class T>
auto MC_base<T>::foo(OBJ_ITR x) -> OBJ_ITR { ... }