"Visual Studio中的模板参数无效"错误,但不是GCC

Phi*_*ipp 8 c++ gcc templates visual-studio

假设你有代码

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; 
}
Run Code Online (Sandbox Code Playgroud)

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>        ]
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Joh*_*itb 11

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

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

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

};
Run Code Online (Sandbox Code Playgroud)

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


突发新闻:即使你这样做,C++ 0x也能完成上述工作EST16<SCEST>.原因是,它表示如果将注入的类名传递给模板模板参数,则注入的类名将被视为模板,而不是类型.因此,对于C++ 0x,GCC将是正确执行它的编译器.