【问题标题】:Is GCC 4.4.1 buggy by not accepting an injected-class-name in a ctor-initializer?通过不接受 ctor-initializer 中的注入类名,GCC 4.4.1 是否存在问题?
【发布时间】:2025-12-15 01:30:02
【问题描述】:

GCC 4.4.1 拒绝在 ctor-initializer 中找到我的 injected-class-name

template <typename T>
struct Base
{
    Base(int x) {}
};

struct Derived : Base<int>
{
    Derived() : Base(2) {}
};

int main()
{
    Derived d;
}
test2.cpp: In constructor "Derived::Derived()":
test2.cpp:9: error: class "Derived" does not have any field named "Base"
test2.cpp:9: error: no matching function for call to "Base<int>::Base()"
test2.cpp:4: note: candidates are: Base<T>::Base(int) [with T = int]
test2.cpp:3: note:                 Base<int>::Base(const Base<int>&)

不过,GCC 4.8 compiles it just fine

我确信这应该可行,但我找不到任何不同意我的标准措辞。

这是 GCC 4.4.1 的错误,对吧?

(我确实搜索了 GCC Bugzilla,但没有弹出任何相关内容。)

【问题讨论】:

  • 你能在构造函数之外使用Base吗?也许 GCC 4.4 认为 Base 是一个从属名称。
  • 不确定,但看起来有点像gcc.gnu.org/bugzilla/show_bug.cgi?id=45515
  • @Simple: Derived 不是模板,Base 不能依赖于任何模板参数
  • @DavidRodríguez-dribeas 我知道,这就是为什么它是一个错误。 GCC 可能认为是。你可以测试typename Derived::Base 看看是不是这个问题。
  • 只是尝试用一些编译它:GCC 4.4.0:失败的 GCC 4.4.1:失败的 GCC 4.4.2:失败的 GCC 4.4.3:失败的 GCC 4.4.4:失败的 GCC 4.4。 5:失败 GCC 4.4.6:失败 GCC 4.4.7:失败 GCC 4.5.0:成功 GCC 4.5.1:成功 GCC 4.5.2:成功 GCC 4.5.3:成功 GCC 4.5.4:成功 GCC 4.6.0:成功 GCC 4.6.1:成功 GCC 4.6.2:成功 GCC 4.6.3:成功 GCC 4.7.0:成功 GCC 4.7.1:成功 GCC 4.7.2:成功 GCC 4.7.3:成功 GCC 4.8.0:成功 GCC 4.8.1:成功 GCC 4.8.2:成功

标签: c++ gcc


【解决方案1】:

使用: Base&lt;int&gt;(2) {}

(编辑:抱歉,我只是拿走了 CRTP 元素,因为它不需要重现)

【讨论】:

  • 这是“是”还是“否”?
  • 当然,这解决了它。但它没有回答问题!
  • 我认为这是相当 4.8 的错误 - 我认为没有模板参数,代码是无效的。虽然没有方便的标准文本来确认它......
  • @WojtekSurowka:injected-class-name 应该在整个类型及其派生类型的范围内。 [C++11: 14.6.1/3] 举了一个例子,虽然不是相当这个。
  • @Erbureth: [C++11: 14.6.1/4]: 查找注入类名 (10.2) 在某些情况下可能会导致歧义(例如,如果在多个基类)。如果找到的所有注入类名都引用同一个类模板的特化,并且如果该名称用作模板名,则引用是指类模板本身而不是其特化,并且不是模棱两可。
【解决方案2】:

是的,它一个错误。

如果没有 ctor-initialiser,我可以更简单地重现它:

template <typename T>
struct Base
{
};

struct Derived : Base<int>
{
    Base* ptr;
};

int main()
{
    Derived d;
}

/**
 * in GCC 4.4.1:
 * 
 * error: ISO C++ forbids declaration of "Base" with no type
 */

还有:

[C++11: 14.6.1/4]: 查找 injected-class-name (10.2) 在某些情况下可能会导致歧义(例如,如果在多个基类中找到它)。如果找到的所有注入类名称都引用同一个类模板的特化,并且如果该名称用作 template-name,则该引用引用类模板本身而不是其专业化,并没有歧义。 [示例:

template <class T> struct Base { };
template <class T> struct Derived: Base<int>, Base<char> {
   typename Derived::Base b;            // error: ambiguous
   typename Derived::Base<double> d;    // OK
};

——结束示例]

请注意,我的明确用法几乎等同于“OK”。好的,所以Derived 在这里是一个类模板,而不是在我的示例中,所以它不是相当 相同的示例。但现在我很满意 14.6.1 的整体使我的代码合法。

原来它被提升为GCC bug 45515,但由于当时它已被固定在 head 上,所以关于它的细节很少。

谢谢BoBTFish

【讨论】:

    最近更新 更多