"命名构造函数,而不是类型"在G ++ 4.4.7中

时间:2017-05-31 22:22:02

标签: c++ gcc

我有以下简单的C ++代码:

#include <cstdio>

class A
{
public:
    A(int y) : x(y) {}
    A& operator=(const A& rhs);
    int x;
};

A::A& A::operator=(const A& rhs) { this->x = rhs.x; return *this; }

int main(int, char**)
{
    A a1(5);
    A a2(4);

    printf("a2.x == %d\n", a2.x);

    a2 = a1;

    printf("a2.x == %d\n", a2.x);

    return 0;
}

A operator=()函数定义所在的第11行格式错误......或者至少我相信如此。正如预期的那样,G ++ 4.7.4以及我尝试过的每个较新版本的GCC都会引发以下错误:

main.cpp:11:1: error: ‘A::A’ names the constructor, not the type

奇怪的是,G ++ 4.4.7成功地编译了这个程序,没有任何警告,甚至打印4和5,正如预期的那样,如果第11行被正确写入(即只有A&而不是{{1 }})。

有人可以帮我解释G ++ 4.4.7到底发生了什么吗?这只是该版本中的一个错误(虽然是一个非常古老的错误,但仍然使用它我们感到羞耻)?我认为标准会明确说明必须如何声明和定义A::A&函数。

2 个答案:

答案 0 :(得分:5)

有一个related bug in g++。它已在版本4.5.0中修复,因此4.4.7仍然有它。

以下是错误说明:

  

cc1plus没有正确实现类名注入。   特别是下面的剪辑应该被拒绝   A :: A没有命名类型(它指定一个构造函数)

struct A { };

int main()
{
    A::A a;       // should be an ERROR
}

虽然此错误的症状与您描述的不同,但在这两种情况下,编译器在将A::A实际命名为构造函数时将其视为类型名称。我很确定这两种行为具有相同的根本原因,这是4.5.0版本之前范围分辨率的较差实现。

答案 1 :(得分:1)

在dasblinkenlight的correct answer上展开 - C ++ 03标准在[class.qual]明确禁止他和我的代码:

  

如果嵌套名称说明符指定了C类和名称   在嵌套名称说明符之后指定,当在C中查找时,是   注入类的C(第9条),而是考虑名称   命名类C的构造函数。应使用这样的构造函数名称   仅在出现的构造函数定义的 declarator-id 中   在类定义之外。 [示例:

struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba; // object of type A
A::A a;  // error, A::A is not a type name
     

- 示例]