“无效的模板参数” Visual Studio 中出现错误,但 GCC 中没有错误

发布于 2024-10-22 12:30:29 字数 1054 浏览 0 评论 0原文

假设您的代码

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 更好的便携式解决方案?

谢谢!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泼猴你往哪里跑 2024-10-29 12:30:29

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

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

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

};

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


突发新闻:即使您执行EST16,C++0x 也会使上述工作正常进行。原因是,它表示如果将注入的类名传递给模板模板参数,则注入的类名将被视为模板,而不是类型。因此,对于 C++0x,GCC 将是正确执行此操作的编译器。

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.

暖伴 2024-10-29 12:30:29

如果您将初始化程序更改为仅引用模板类名称 EST16,它会在 VS 上编译。 IE:

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

It compiles on VS if you change the initialiser to just refer to the template class name, EST16. I.e.:

class NotWorkingChild : public EST16<SCEST>
{
public:
    NotWorkingChild()
        : EST16(1.0)
    {
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文