g++模板bug还是VC太自由?

发布于 2024-10-22 05:35:04 字数 747 浏览 1 评论 0 原文

我正在用 C++ 编写一段高度模板化的代码。它在 VS 2005 中运行得很好,但是当我尝试在 g++ 中编译它时,我遇到了一些非常奇怪的错误。

基本代码段(简化到最低限度,也不能编译)如下:

template <class Actual>
class Generic
{
public:
    typedef Actual ThisType;
};

template <class Actual>
class Intermediate : public Generic<Actual>
{
};

template <class Q>
class Derived : public Intermediate<Derived<Q> >
{
public:
    void FooBar()
    {
        ThisType q;
    }
};

错误是: “‘ThisType’未在此范围内声明” 在声明“q”的行中。

奇怪的是,当 Derived 不是模板而是普通类时,一切正常。为什么编译器会在实例化模板函数之前检查它的实现?我知道 VC++ 在编译模板时检查得太少(未使用的模板甚至可能包含语法错误的代码) - 但 g++ 在这里检查不是太多了吗?我尝试添加一个 typename 关键字,希望渺茫,但也失败了。有什么方法可以让 ThisType 按预期工作吗?我害怕手动将其添加到每个派生类中的想法 - 它很麻烦、多余、不优雅并且会引发错误。

此致, 米兹

I am writing a heavily templated piece of code in C++. It worked perfectly in VS 2005 but when I try to compile it in g++ I get some really strange errors.

The essential piece of code (simplified to a minimum, doesn't compile either) is as follows:

template <class Actual>
class Generic
{
public:
    typedef Actual ThisType;
};

template <class Actual>
class Intermediate : public Generic<Actual>
{
};

template <class Q>
class Derived : public Intermediate<Derived<Q> >
{
public:
    void FooBar()
    {
        ThisType q;
    }
};

The error is:
"'ThisType' was not declared in this scope"
in the line where 'q' is being declared.

Curiously, everything works fine when Derived is not a template but a plain class. Why would compiler look into template function implementation before it is even instantiated? I know that VC++ checks far too little when compiling templates (unused templates can even contain syntactically incorrect code) - but isn't g++ checking too much here? I tried adding a typename keyword with little hope and it fails too. Is there any way to get ThisType to work as expected? I dread the thought of adding it manually to every single derived class - it's cumbersome, redundant, inelegant and error-inducing.

Best regards,
MZ

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

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

发布评论

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

评论(4

拥抱影子 2024-10-29 05:35:04

不会在依赖基类中查找非限定名称(您的基类取决于模板参数Q)。限定该名称,它就会起作用。

typename Derived::ThisType q;

Unqualified names are not looked up in dependent base classes (your base class depends on template parameter Q). Qualify that name, and it will work.

typename Derived::ThisType q;
漆黑的白昼 2024-10-29 05:35:04

相信Comeau 在线编译器

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 19: error: identifier "ThisType" is undefined
          ThisType q;
          ^

"ComeauTest.c", line 19: error: expected a ";" (perhaps on the previous statement)
          ThisType q;
                   ^

2 errors detected in the compilation of "ComeauTest.c".

不考虑继承类的依赖类型名称,您可以尝试显式请求 ThisType:

typename Intermediate<Derived<Q> >::ThisType q;

Trust in Comeau online compiler!

Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 19: error: identifier "ThisType" is undefined
          ThisType q;
          ^

"ComeauTest.c", line 19: error: expected a ";" (perhaps on the previous statement)
          ThisType q;
                   ^

2 errors detected in the compilation of "ComeauTest.c".

Dependent type names from inherited classes are not taken into account, you might try to explicitly request ThisType:

typename Intermediate<Derived<Q> >::ThisType q;
感受沵的脚步 2024-10-29 05:35:04

该代码确实格式不正确。当基类依赖于模板参数时,在查找非限定名称时,名称查找不会考虑基类。

在您的情况下,将不会在基类 Intermediate 中查找非限定名称 ThisType 。 > 因为您的基类依赖于模板参数 Q

The code is indeed ill-formed. When base class depends on template parameter it is not considered by name lookup when looking for unqualified names.

In your case unqualified name ThisType will not be looked up in base class Intermediate<Derived<Q> > because your base class depends on template parameter Q.

书信已泛黄 2024-10-29 05:35:04

您缺少类型名称

template <class Actual> class Generic { public:
    typedef Actual ThisType; };

template <class Actual> class Intermediate : public Generic<Actual> { };

template <class Q> class Derived : public Intermediate<Derived<Q> > { public:
    void FooBar()
    {
        typename Derived::ThisType q;
        return *this;
    } };

int main(){}

You are missing a typename

template <class Actual> class Generic { public:
    typedef Actual ThisType; };

template <class Actual> class Intermediate : public Generic<Actual> { };

template <class Q> class Derived : public Intermediate<Derived<Q> > { public:
    void FooBar()
    {
        typename Derived::ThisType q;
        return *this;
    } };

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