Dlaczego to wywołuje domyślny konstruktor?

80
struct X
{
    X()    { std::cout << "X()\n";    }
    X(int) { std::cout << "X(int)\n"; }
};

const int answer = 42;

int main()
{
    X(answer);
}

Spodziewałbym się, że to też się wydrukuje

  • X(int), ponieważ X(answer);można to zinterpretować jako odlew zint do Xlub
  • w ogóle nic, ponieważ X(answer); mogłoby być zinterpretowane jako deklaracja zmiennej.

Jednak drukujeX() i nie mam pojęcia, dlaczego X(answer);miałbym wywołać domyślny konstruktor.

PUNKTY DODATKOWE: Co musiałbym zmienić, aby uzyskać tymczasową zamiast zmiennej deklarację?

fredoverflow
źródło
1
X (odpowiedź (int)); jednak daje prawidłowy wynik.
Inisheer
2
@JTA I w końcu X(int(answer));nic nie drukuje, bo to deklaracja funkcji :)
fredoverflow
1
w ogóle nic, ponieważ X (odpowiedź); można by zinterpretować jako deklarację zmiennej. Ta deklaracja byłaby również definicją i wyzwala wykonanie domyślnego konstruktora ... co z kolei oznacza, że ​​odpowiedziałeś na własne pytanie.
David Rodríguez - dribeas
6
@David no double(expresso);you go, zadeklarowany specjalnie dla Ciebie;)
fredoverflow
2
@FredOverflow: Potrzebuję definicji, aby go używać, ponieważ nie czuję żadnego efektu ...
David Rodríguez - dribeas

Odpowiedzi:

73

w ogóle nic, ponieważ X (odpowiedź); można by zinterpretować jako deklarację zmiennej.

Twoja odpowiedź jest tutaj ukryta. Jeśli deklarujesz zmienną, wywołujesz jej domyślny ctor (jeśli nie jest to POD i tak dalej).

Przy zmianie: aby uzyskać tymczasowy, masz kilka opcji:

Xeo
źródło
4
Wydaje się, static_cast<X>(answer)że odpowiedź jest „najbardziej C ++” - jest nawet zalecana przez starą dokumentację GCC jako sposób na wymuszenie wartości r.
Kerrek SB,
Czy inicjalizator nawiasów klamrowych również nie spowoduje powstania kopii?
rubenvb
@rubenvb: Dlaczego miałoby to robić? To tylko nowy, wymyślny sposób mówienia X(answer)i gwarantuje wezwanie lekarza.
Xeo,
@Xeo: ponieważ składnia inicjatora nawiasów klamrowych przyjmuje argumenty według wartości? (<- uwaga na znak zapytania)
rubenvb
4
@KerrekSB Ale na pewno tylko przed C ++ 11, nie? Teraz kanoniczna odpowiedź będzie X{answer}.
Konrad Rudolph
66

Nawiasy są opcjonalne. To, co powiedziałeś, jest identyczne X answer;i jest to oświadczenie deklaracji.

Kerrek SB
źródło
9

Jeśli chcesz zadeklarować zmienną typu X, powinieneś to zrobić w ten sposób:

X y(answer);
huysentruitw
źródło
1
Nie pytał, jak sprawić, by zadzwonił do X(int)lekarza.
Xeo,
Tak, ale mam małe przeczucie, że to właśnie zamierzał zrobić :)
huysentruitw
6
@WouterH: Właściwie, znając Freda, jest to mało prawdopodobne. Jest jednym z tych ludzi, którzy lubią zgłębiać ciemne zakamarki standardu C ++ i próbować go zrozumieć. W pewnej RPG straciłby już wszystkie punkty zdrowia psychicznego;)
Matthieu M.