我在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(临时名称)p4指出:



鉴于此,我在Godbolt上针对ICC 13和Clang 3.3检查了您的示例:ICC在接受符合标准(nontype "Base<A, B>::InBase [with A=A, B=B]" is not a template / typename合格)版本的同时,正确拒绝了带有template的MSVC-ism,而有趣的是,Clang接受了符合标准和不符合typedefs!我在本地的MSVC 11(VS2012)副本也拒绝其中包含templatetypename的版本,并按照错误提示传递模板参数列表(无论如何,格式都是错误的)。

看来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块来笼罩特定于MSVC的typedef版本。

对于pedant:ICC,尽管它在世界的某些角落被撕破了,但实际上它符合C++标准,因为它使用了与Comeau C++相同的EDG前端。

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

10-13 04:03