2017-08-18 21 views
6
#include <iostream> 

struct Box 
{ 
    Box()   { std::cout << "constructor called" << std::endl; } 
    Box(const Box&) { std::cout << "Copy constructor called" << std::endl; } 
    Box(Box&&)  { std::cout << "Move constructor called" << std::endl; } 
    void run() const { std::cout << "Run" << std::endl;} 
}; 

int main() 
{ 
    Box a(Box()); 
    a.run(); 
} 

(demo)Żaden konstruktorów zwane przechodząc Anonymous obiekt jako argument

W powyższym kodu I był oczekiwany albo Copy Constuctor lub Move Constructor nazywać przechodząc anonimowego przedmiotu Box() jako argument. Ale żaden z nich nie został wezwany. Prawdopodobnie powodem może być copy elision. Ale nawet konstruktor nie jest wymagany do anonimowego obiektu A(). W rzeczywistości powyższy kod nie kompiluje się i wywołując kompilator funkcji run() dał następujący błąd.

a.cpp: In function ‘int main()’: 
a.cpp:28:7: error: request for member ‘run’ in ‘a’, which is of non-class type ‘Box(Box (*)())’ 
    a.run(); 

Więc kiedy wpisujemy Box a(Box()), co się dzieje? Co powstaje?

+3

Zostałeś ugryziony przez MVP. Uważa, że ​​'Box a (Box()); jest deklaracją funkcji zwanej' a' zwracającej 'Box'. – Borgleader

+0

@YSC Nie jestem pewien, czy zgadzam się z formatowaniem - wolałem poprzednią wersję. – pingul

+1

Krótkie kody @pingul przyciągają więcej uwagi na SO, a moja edycja nie ma (mam nadzieję) zmiany pierwotnej intencji OP. Ale to zdecydowanie ich wezwanie do wycofania tego. – YSC

Odpowiedz

15

Jest to przypadek Most Vexing Parse. Kiedy coś może zostać przetworzone jako deklaracja funkcji, tak właśnie jest.

Box a(Box()) 

jest deklaracja funkcji o nazwie a biorąc funkcję typu Box (*)() jako argument i przekazujących Box.

Rozwiązaniem jest użyć (nowa w C++ 11) aggregate initialization do budowy swoich obiektów:

Box a{Box{}} 

(demo)


MVP został omówiony w swojej najprostszej formie, w to pytanie stackoverflow Most vexing parse: why doesn't A a(()); work?

Jeśli masz wyrażenie wewnątrz to to jest ważna. Na przykład:

((0));//compiles 

Aby dowiedzieć się więcej o tym, jak języki są zdefiniowane, i jak działają kompilatory, należy dowiedzieć się o Formal language theory lub dokładniej Context Free Grammars (CFG) i powiązane materiały jak automat skończony. Jeśli jesteś zainteresowany tym, że strony wikipedia nie będą wystarczające, będziesz musiał dostać książkę.

Powiązane problemy