Jako ciekawa kontynuacja (choć nie ma to dużego znaczenia praktycznego) mojego poprzedniego pytania: Dlaczego C ++ pozwala nam umieszczać nazwę zmiennej w nawiasach podczas deklarowania zmiennej?
Dowiedziałem się, że połączenie deklaracji w nawiasach z właściwością wstrzykniętej nazwy klasy może prowadzić do zaskakujących wyników w zachowaniu kompilatora.
Spójrz na następujący program:
#include <iostream>
struct B
{
};
struct C
{
C (){ std::cout << "C" << '\n'; }
C (B *) { std::cout << "C (B *)" << '\n';}
};
B *y = nullptr;
int main()
{
C::C (y);
}
Kompilacja z g ++ 4.9.2 daje następujący błąd kompilacji:
main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
Kompiluje się pomyślnie z MSVC2013 / 2015 i drukuje
C (B *)
Kompiluje się pomyślnie z clang 3.5 i drukuje
C
Tak więc obowiązkowe pytanie brzmi, który z nich jest właściwy? :)
(Silnie kołysałem się w kierunku wersji clang i sposób, w jaki msvc przestał deklarować zmienną po zmianie typu, a technicznie jego typedef wydaje się trochę dziwny)
C::C
nie nazywa typu, nazywa funkcję, więc GCC ma rację imo.
C::C y;
nie ma sensu, prawda? Ani też.C::C (y);
Na początku myślałem, że to wystąpienie Most-Vexing-Parse stackoverflow.com/questions/tagged/most-vexing-parse , ale teraz myślę, że jest to po prostu niezdefiniowane zachowanie, co oznacza, że wszystkie trzy kompilatory mają „rację”.