2017-05-31 14 views
6

mam następujący prosty kod C++:"nazwiska konstruktora, a nie typu" 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; 
} 

linii 11, gdzie definicja operator=() funkcji A „s jest co jest źle sformułowany. ... lub przynajmniej tak uważam. Zgodnie z oczekiwaniami, G ++ 4.7.4, jak również każda nowa wersja GCC, że próbowałem, rzuca się następujący błąd:

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

dziwne, chociaż, G ++ 4.4.7 kompiluje program z powodzeniem, bez ostrzeżenia , a nawet drukuje 4 i 5, jak można się było spodziewać, jeśli wiersz 11 został poprawnie napisany (tj. z tylko A& zamiast A::A&).

Czy ktoś może mi pomóc rozszyfrować, co dokładnie się tam dzieje z G ++ 4.4.7? Czy jest to po prostu błąd w tym wydaniu (choć bardzo stary i wstyd, że wciąż go używamy)? Myślę, że standard wyraźnie określałby, w jaki sposób należy zadeklarować i zdefiniować funkcję operator=().

+1

Nie ma wstydu w użyciu starego kompilator obsługuje codebase starszych. Cholernie trudno zdobyć fundusze na ulepszenie łańcucha narzędzi dla działającego produktu. – user4581301

Odpowiedz

5

Był related bug in g++. Zostało to naprawione w wersji 4.5.0, więc 4.4.7 nadal je ma.

Oto opis błędu:

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 
} 

Chociaż objawy tego błędu nie są identyczne, co można opisać w obu przypadkach kompilator traktuje A::A jako nazwa typu, podczas gdy w rzeczywistości nazwy konstruktora. Jestem prawie pewien, że te dwa zachowania mają tę samą główną przyczynę, która jest słabą implementacją rozdzielczości zakresu przed wersją 4.5.0.

1

Rozszerzając dasblinkenlight na correct answer standardem C++ 03 --the wyraźnie zakazuje jego i mój kod w [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]

Powiązane problemy