“无效的模板参数”错误在Visual Studio中但不是GCC [英] "Invalid template argument" error in Visual Studio but not GCC

查看:241
本文介绍了“无效的模板参数”错误在Visual Studio中但不是GCC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有代码

 模板< template< class> class BaseType> 
class EST16
:public BaseType< int>
{
public:
EST16(double d)
{
}
};

模板< class T>
class SCEST
{
T y;
};
typedef EST16< SCEST> EST16_SC;
class Child
:public EST16_SC
{
public:
Child()
:EST16_SC(1.0)
{
}

};



class NotWorkingChild
:公共EST16< SCEST>
{
public:
NotWorkingChild()
:EST16< SCEST>(1.0)
{
}

};



TEST(TemplateTest,TestInstantiate)
{
Child child;
NotWorkingChild notWorkingChild;

Child和NotWorkingChild的区别仅在于typedef。在GCC中都编译时,在Visual Studio中,NotWorkingChild的构造函数会产生以下错误:

  2> .. \..\\ \\..\src\itenav\test\SCKFErrorStateTest.cpp(43):错误C3200:'SCEST< T>':模板参数'BaseType'的无效模板参数,期望类模板
2> ;与
2> [
2> T = int
2> ]

你能解释为什么会出现这种情况吗?有没有比typedef更好的便携式解决方案?



感谢!

解决方案

<错误消息是因为 NotWorkingChild SCEST 派生(间接),这使得<$ c $在 NotWorkingChild 范围内的c> SCEST 引用类 SCEST< int> ,而不是模板。 MSVC拒绝这个是正确的,GCC4.5也应该拒绝这个(GCC4.5有更正确的注入类名称查找)。



以下解决方案可用于两种编译器

  class NotWorkingChild 
:公共EST16< SCEST>
{
public:
NotWorkingChild()
:EST16< :: SCEST>(1.0)
{
}

};

请注意,我们使用范围解析运算符并需要在 :: (令牌<:否则会被视为有向图)。




突发新闻:即使你做了 EST16< SCEST> 。原因是,它表示如果将注入的类名称传递给模板模板参数,则将注入的类名称视为模板,而不是视为类型。因此,对于C ++ 0x,GCC是编译器正确执行的。

suppose you have the code

template <template<class> class BaseType>
class EST16
    : public BaseType<int>
{
public:
    EST16(double d) 
    {
    }
};

template <class T>
class SCEST
{
    T y;
};
typedef EST16<SCEST> EST16_SC;
class Child
    : public EST16_SC
{
public:
    Child()
        : EST16_SC(1.0)
    {
    }

};



class NotWorkingChild
    : public EST16<SCEST>
{
public:
    NotWorkingChild()
        : EST16<SCEST>(1.0)
    {
    }

};



TEST(TemplateTest, TestInstantiate)
{
    Child child;
    NotWorkingChild notWorkingChild; 
}

Child and NotWorkingChild differ only by the typedef. In GCC both compile, in Visual Studio the constructor of NotWorkingChild produces the following error:

2>..\..\..\src\itenav\test\SCKFErrorStateTest.cpp(43) : error C3200: 'SCEST<T>' : invalid template argument for template parameter 'BaseType', expected a class template
2>        with
2>        [
2>            T=int
2>        ]

Can you explain why this is the case? Is there a better portable solution than the typedef?

Thanks!

解决方案

The error message is because NotWorkingChild derives (indirectly) from SCEST<int>, which makes SCEST inside the scope of NotWorkingChild refer to the class SCEST<int>, instead of the template. MSVC is correct to reject this, and GCC4.5 should reject this too (GCC4.5 has more correct injected class name lookup).

Here is a solution that might work for both compilers

class NotWorkingChild
    : public EST16<SCEST>
{
public:
    NotWorkingChild()
        : EST16< ::SCEST >(1.0)
    {
    }

};

Notice that we use the scope resolution operator and need to put a space before :: (the token <: would otherwise be taken as a digraph).


Breaking News: C++0x will make the above work even if you do EST16<SCEST>. The reason is, that it says that if the injected class name is passed to a template template parameter, the injected class name is treated as a template, instead of as a type. Therefor, for C++0x, GCC would be the compiler doing it correctly.

这篇关于“无效的模板参数”错误在Visual Studio中但不是GCC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆