2017-05-31 154 views
6

我有以下簡單的C++代碼:11「的名稱的構造,而不是類型」在G ++ 4.4.7

#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; 
} 

線,其中Aoperator=()函數的定義是在,格式錯誤。至少,我相信是的。正如預期的那樣,G ++ 4.7.4,以及海灣合作委員會的每一個新版本,我已經試過了,引發以下錯誤:

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

奇怪的是,雖然,G ++ 4.4.7編譯成功此方案,沒有警告,甚至打印4和5,如果第11行被正確寫入(即僅用A&而不是A::A&),就會如預期的那樣。

有人可以幫助我解釋G ++ 4.4.7究竟發生了什麼嗎?這只是該版本中的一個錯誤(雖然是一個非常古老的版本,並且仍然在使用它)我們感到羞愧。我認爲標準將明確說明如何聲明和定義operator=()函數。

+1

有一個在使用舊的編譯器支持傳統的代碼庫沒有羞恥。很難獲得資金來升級工作產品的工具鏈。 – user4581301

回答

5

有一個related bug in g++。它在4.5.0版本中得到了修復,所以4.4.7仍然有它。

下面是錯誤描述:

cc1plus does not implement the class name injection correctly. In particular the snipped below should be rejected on the basis that A::A does not name a type (it designates a constructor)

struct A { }; 

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

雖然這個bug的症狀並不等同於你的描述,在這兩種情況下,編譯器將A::A作爲一個類型名稱,當它真正的名字的構造函數。我非常肯定,這兩種行爲有着相同的根本原因,這是4.5.0版之前的範圍分辨率實施不力。

1

擴展在dasblinkenlight的correct answer --the C++ 03標準明確地禁止他和我在[class.qual]代碼:

If the nested-name-specifier nominates a class C, and the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (clause 9), the name is instead considered to name the constructor of class C. Such a constructor name shall be used only in the declarator-id of a constructor definition that appears outside of the class definition. [Example:

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 

—end example]