Почему это вызывает конструктор по умолчанию?

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 (ответ), но если вы создадите экземпляр, инициализированный с помощью int, скажем, X xx (ответ), вы получите печать X (int).   -  person Michael    schedule 27.07.2012
comment
Х((целое)ответ); однако дает правильный результат.   -  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(answer); может быть интерпретировано как объявление переменной. Это объявление также будет определением и вызовет выполнение конструктора по умолчанию... что, в свою очередь, означает, что вы ответили на свой вопрос.   -  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 Но наверняка только до С++ 11, нет? Теперь каноническим ответом будет X{answer}. - person Konrad Rudolph; 28.07.2012
comment
Кто-нибудь может объяснить, как X(answer) эквивалентно X answer? - person Sam; 18.08.2013
comment
@SAM: Потому что так сказано в стандарте. Как говорит ответ Керрека, скобки необязательны. - 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