Защо това извиква конструктора по подразбиране?

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

const int answer = 42;

int main()
{
    X(answer);
}

Бих очаквал и това да бъде отпечатано

  • X(int), тъй като X(answer); може да се интерпретира като преобразуване от int към X, или
  • изобщо нищо, защото X(answer); може да се интерпретира като декларация на променлива.

Обаче отпечатва X() и нямам представа защо X(answer); би извикал конструктора по подразбиране.

БОНУС ТОЧКИ: Какво трябва да променя, за да получа временна вместо променлива декларация?


person fredoverflow    schedule 27.07.2012    source източник
comment
Прави същото, ако промените int answer -› всеки друг тип.   -  person Flexo    schedule 27.07.2012
comment
Не съм сигурен какво трябва да прави X(answer), но ако създадете екземпляр, инициализиран с int, да кажем X xx(answer), ще получите отпечатъка X(int).   -  person Michael    schedule 27.07.2012
comment
X((int)отговор); обаче дава правилния резултат.   -  person Inisheer    schedule 27.07.2012
comment
@JTA: Защото това никога не може да се интерпретира като декларация, така че трябва да бъде извикване на конструктор.   -  person Xeo    schedule 27.07.2012
comment
@JTA И накрая, X(int(answer)); не отпечатва нищо, защото е декларация на функция :)   -  person fredoverflow    schedule 27.07.2012
comment
съвсем нищо, защото X(отговор); може да се интерпретира като декларация на променлива. Тази декларация също би била дефиниция и тя задейства изпълнението на конструктора по подразбиране... което от своя страна означава, че сте отговорили на собствения си въпрос.   -  person David Rodríguez - dribeas    schedule 27.07.2012
comment
@David Закъсняваш малко за партито, мога ли да ти донеса питие? ;)   -  person fredoverflow    schedule 27.07.2012
comment
@FredOverflow: Направете това двойно експресо...   -  person David Rodríguez - dribeas    schedule 27.07.2012
comment
@David double(expresso); ето го, обявено само за вас ;)   -  person fredoverflow    schedule 27.07.2012
comment
@FredOverflow: трябва да имам нужда от дефиниция, за да го използвам, защото не усещам ефект...   -  person David Rodríguez - dribeas    schedule 27.07.2012


Отговори (3)


абсолютно нищо, защото X(отговор); може да се тълкува като декларация на променлива.

Вашият отговор е скрит тук. Ако декларирате променлива, вие извиквате нейния ctor по подразбиране (ако не е POD и всички тези неща).

За вашата редакция: За да получите временна, имате няколко опции:

person Xeo    schedule 27.07.2012
comment
static_cast<X>(answer) се усеща най-добре като C++ отговор -- дори се препоръчва от стар GCC документация като начин за налагане на rvalue. - person Kerrek SB; 27.07.2012
comment
Инициализаторът на скоби също няма ли да повлече копие? - person rubenvb; 27.07.2012
comment
@rubenvb: Защо? Това е просто фантастичен нов начин да се каже X(answer) и гарантира повикване на ctor. - person Xeo; 27.07.2012
comment
@Xeo: защото синтаксисът на инициализатора на фигурни скоби приема аргументите си по стойност? (‹- обърнете внимание на въпросителния знак) - person rubenvb; 27.07.2012
comment
@rubenvb: О, нямах предвид, че answer се копира, имах предвид, когато X се връща от вътрешността на ламбда. - person Xeo; 27.07.2012
comment
@KerrekSB Но със сигурност само преди C++11, нали? Сега каноничният отговор ще бъде X{answer}. - person Konrad Rudolph; 28.07.2012
comment
Може ли някой да обясни как X(answer) е еквивалентно на X answer? - person Sam; 18.08.2013
comment
@SAM: Защото стандартът го казва. Както се казва в отговора на Kerrek, скобите не са задължителни. - person Xeo; 19.08.2013
comment
@Xeo Обикновен човек! Просто ми кажете откъде знаете всяка малка подробност за c++? Не питам само за този въпрос, но видях и другите ви отговори. Искам да кажа, просто погледнетеvoid(), X(answer); Как, за бога, разбрахте това?!?! Също така какво препращате към C++? Четох TC++PL (3-то и 4-то издание). Освен това как научихте C++11 за толкова кратко време? - person Sam; 19.08.2013
comment
@Xeo И колко години опит в програмирането ти трябваха, за да стигнеш до този етап? - person Sam; 19.08.2013
comment
@SAM: Препоръчвам да се присъедините към мен в стаята за чат в Lounge (проверете профила ми), тъй като това тук вече не е по темата. :) - person Xeo; 19.08.2013

Скобите не са задължителни. Това, което казахте, е идентично с X answer; и е декларация.

person Kerrek SB    schedule 27.07.2012

Ако искате да декларирате променлива от типа X, трябва да го направите по следния начин:

X y(answer);
person huysentruitw    schedule 27.07.2012
comment
Той не попита как да го накара да извика X(int) ctor. - person Xeo; 27.07.2012
comment
Да, но имам малко чувство, че това беше нещото, което той трябваше да направи :) - person huysentruitw; 27.07.2012
comment
@WouterH: Всъщност, познавайки Фред, е малко вероятно. Той е един от онези хора, които обичат да изследват тъмните ъгли на стандарта C++ и да се опитват да го разберат. В определена ролева игра той вече би загубил всичките си точки за разум ;) - person Matthieu M.; 27.07.2012