[英]MSVC: “use of class template requires template argument list” inside STL containers
I have an issue with nested template classes on MSVC 12 and GCC 4.8. 我在MSVC 12和GCC 4.8上的嵌套模板类有问题。 I've reduced it to the following snippet: 我将其简化为以下代码段:
#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;
};
When I use the MSVC variant of MyInBase
on GCC, it just tells me to add typename
and template
, which I find understandable. 当我在GCC上使用MyInBase
的MSVC变体时,它只是告诉我添加typename
和template
,我认为这是可以理解的。 When I use the GCC variant on MSVC (which I believe is the correct one), it reports this: 当我在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'
Is the MSVC error correct? MSVC错误正确吗? If yes, how can I fix it? 如果是,我该如何解决?
MSVC is rejecting valid code here, as N3337 14.2 (temp.names) p4 states: MSVC在这里拒绝有效代码,因为N3337 14.2(临时名称)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 keywordtemplate
. 或->
在postfix-expression中,或者在qualified-id中的嵌套名称说明符之后,并且postfix-expression的对象表达式取决于类型,或者qualified-id中的nested-name-specifier引用一个依赖类型,但名称不是当前实例(14.6.2.1)的成员,成员模板名称必须以关键字template
为前缀。 Otherwise the name is assumed to name a non-template. 否则,假定该名称命名为非模板。
Given this, I checked your sample against ICC 13 and Clang 3.3 on Godbolt : ICC correctly rejects this MSVC-ism with nontype "Base<A, B>::InBase [with A=A, B=B]" is not a template
while accepting the conformant ( typename
/ template
qualified) version, whereas Clang, interestingly enough, accepts both the conformant and the nonconformant typedefs! 鉴于此,我在Godbolt上针对ICC 13和Clang 3.3检查了您的示例:ICC正确拒绝了nontype "Base<A, B>::InBase [with A=A, B=B]" is not a template
MSVC-ism nontype "Base<A, B>::InBase [with A=A, B=B]" is not a template
在接受符合的( typename
/ template
合格)版本,而铛,有趣的是,同时接受的符合性和不符合标准的typedef! My local copy of MSVC 11 (VS2012) also rejects the version with template
and typename
in it, as well as passing a template argument list as the error suggests (which is ill-formed in any case). 我在本地的MSVC 11(VS2012)副本也拒绝其中带有template
和typename
的版本,并拒绝错误提示的模板参数列表(无论如何格式错误)。
It appears that the template
keyword is what is tripping MSVC up, too, which prevents GCC 4.9's suggestion of using an otherwise-redundant Derived::MyBase::template InBase<A, B>
to force the expression into a dependent context without using typename
from working. 看来template
关键字也是使MSVC Derived::MyBase::template InBase<A, B>
,这也阻止了GCC 4.9建议使用否则为冗余的Derived::MyBase::template InBase<A, B>
来强制表达式进入依赖上下文而没有使用typename
从工作。
The Visual Studio devs are already aware of a very similar issue to this . Visual Studio开发人员已经意识到与此类似的问题 。 As to working around it, though? 至于如何解决呢? You'll just have to use a #ifdef _MSC_VER
block to cage the MSVC-specific version of the typedef. 您只需要使用#ifdef _MSC_VER
块来笼罩特定于MSVC的typedef版本。
For pedants: ICC, for all it gets ripped on in some corners of the world, does conform to the C++ standards in practice, as it uses the same EDG frontend as Comeau C++. 对于pedant:ICC,尽管它在世界的某些角落被撕破了, 但实际上它符合C ++标准,因为它使用了与Comeau C ++相同的EDG前端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.