假设你有代码

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和NotWorkingChild的区别仅在于typedef。在GCC中都进行编译,在Visual Studio中,NotWorkingChild的构造函数产生以下错误:
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>        ]

您能解释为什么会这样吗?有没有比typedef更好的便携式解决方案?

谢谢!

最佳答案

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

这是一个可能对两个编译器都适用的解决方案

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

};

请注意,我们使用范围解析运算符,并且需要在::之前放置一个空格(否则将把<:标记视为有向图)。

最新新闻:即使您执行EST16<SCEST>,C++ 0x仍可完成上述工作。原因是,它说如果将注入(inject)的类名传递给模板template参数,则将注入(inject)的类名视为模板而不是类型。因此,对于C++ 0x,GCC将是正确执行此操作的编译器。

关于c++ - 在Visual Studio中出现"Invalid template argument"错误,但在GCC中没有,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5315134/

10-11 22:54