c++ - MSVC : "use of class template requires template argument list" inside STL containers

标签 c++ templates visual-c++ gcc stl

我在 MSVC 12 和 GCC 4.8 上遇到嵌套模板类问题。我已将其简化为以下片段:

#include <vector>
#include <list>

template <typename A, typename B>
struct Base
{
  template <typename A2, typename B2> struct InBase { };
};

template <typename A, typename B>
struct Derived : public Base<A, B>
{
  typedef Base<A, B> MyBase;

  // this works on GCC 4.8
  typedef typename MyBase::template InBase<A, B> MyInBase;
  // this works on MSVC 12
  typedef MyBase::InBase<A, B> MyInBase;

  typedef std::vector<MyInBase*> MyInBaseVector;
  typedef std::list<MyInBase*> MyInBaseList;

  MyInBaseList list;
};

当我在 GCC 上使用 MyInBase 的 MSVC 变体时,它只是告诉我添加 typenametemplate,我觉得这是可以理解的。当我在 MSVC 上使用 GCC 变体(我相信这是正确的)时,它会报告以下内容:

deptypes.cpp(20) : error C2955: 'Base<A,B>::InBase' : use of class template requires template argument list
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'
    deptypes.cpp(24) : see reference to class template instantiation 'Derived<A,B>' being compiled
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\vector(648) : error C2955: 'Base<A,B>::InBase' : use of class template requires template argument list
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'
deptypes.cpp(21) : error C2955: 'Base<A,B>::InBase' : use of class template requires template argument list
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\list(859) : error C2955: 'Base<A,B>::InBase' : use of class template requires template argument list
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'
    deptypes.cpp(7) : see declaration of 'Base<A,B>::InBase'

MSVC 错误是否正确?如果是,我该如何解决?

最佳答案

MSVC 在此拒绝有效代码,如 N3337 14.2 (temp.names) p4 状态:

When the name of a member template specialization appears after . or -> in a postfix-expression or after a nested-name-specifier in a qualified-id, and the object expression of the postfix-expression is type-dependent or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.

鉴于此,我在 Godbolt 上对照 ICC 13 和 Clang 3.3 检查了您的示例:ICC 正确地拒绝了这种 MSVC 主义 nontype "Base<A, B>::InBase [with A=A, B=B]" is not a template同时接受一致的( typename/template 限定)版本,而有趣的是,Clang 既接受一致的 不一致的 typedef!我的 MSVC 11 (VS2012) 本地拷贝也拒绝带有 template 的版本和typename其中,以及按照错误提示传递模板参数列表(在任何情况下都是格式错误的)。

看来 template关键字也是导致 MSVC 失败的原因,它阻止了 GCC 4.9 使用其他冗余的建议 Derived::MyBase::template InBase<A, B>强制表达式进入依赖上下文而不使用 typename从工作中。

Visual Studio 开发人员已经 aware of a very similar issue to this 。不过,至于解决这个问题吗?您只需使用 #ifdef _MSC_VER block 来限制 MSVC 特定版本的 typedef。

对于学究来说:ICC,尽管它在世界某些角落被蹂躏,但在实践中确实符合 C++ 标准,因为它使用与 Comeau C++ 相同的 EDG 前端。

关于c++ - MSVC : "use of class template requires template argument list" inside STL containers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26037290/

相关文章:

c++ - getline 与 istream_iterator

c++ - 采用引用类型参数的函数模板

c++ - 专门化后的显式实例化

visual-c++ - 无法使用{0}初始化float数组

c++ - 在C++中的Switch Case中创建对象之后,调用该对象的方法

c# - 如何取消设置整数中的特定位

c++ - 匿名命名空间如何避免生成全局静态变量?

c++ - 模板编程和位域

c++ - 为什么我得到 "vector iterators incompatible"?

c++ - 基本的 DirectX11 问题,只要我开始在屏幕上绘制任何东西,代码就会崩溃。还有助于 Netbeans 配置