Чому це викликає конструктор за замовчуванням?


80
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);називати конструктор за замовчуванням.

БОНУСНІ ТОЧКИ: Що б мені змінити, щоб отримати тимчасову замість декларації змінної?


1
X ((int) відповідь); однак дає правильний результат.
Inisheer

2
@JTA І нарешті, X(int(answer));нічого не друкує, тому що це оголошення функції :)
fredoverflow

1
зовсім нічого, тому що X (відповідь); можна інтерпретувати як оголошення змінної. Це оголошення також було б визначенням, і воно ініціює виконання конструктора за замовчуванням ... що, у свою чергу, означає, що ви відповіли на власне запитання.
Девід Родрігес - dribeas

6
@David double(expresso);there you go, оголошений саме для вас;)
fredoverflow

2
@FredOverflow: Мені потрібне визначення, щоб використовувати його, тому що я не відчуваю жодного ефекту ...
Девід Родрігес - dribeas

Відповіді:


73

зовсім нічого, тому що X (відповідь); можна інтерпретувати як оголошення змінної.

Ваша відповідь схована тут. Якщо ви оголосите змінну, ви викличете її ctor за замовчуванням (якщо вона не є POD і все таке інше).

Під час редагування: щоб отримати тимчасове, у вас є кілька варіантів:


4
Відповідь static_cast<X>(answer)"найбільш C ++" - це навіть рекомендовано у старій документації GCC як спосіб примусового значення rvalue.
Kerrek SB

Хіба на ініціалізаторі дужок також не виникне копія?
rubenvb

@rubenvb: Чому? Це просто вигадливий новий спосіб сказати X(answer)і гарантує дзвінок ктора.
Xeo,

@Xeo: оскільки синтаксис ініціалізатора фігурних дужок бере свої аргументи за значенням? (<- зверніть увагу на знак запитання)
rubenvb

4
@KerrekSB Але, звичайно, лише до С ++ 11, ні? Тепер канонічна відповідь буде X{answer}.
Конрад Рудольф

66

Дужки необов’язкові. Те, що ви сказали, ідентичне X answer;, і це декларація.


9

Якщо ви хочете оголосити змінну типу X, вам слід зробити це таким чином:

X y(answer);

1
Він не запитував, як змусити це зателефонувати X(int)ctor.
Xeo,

Так, але я маю невелике відчуття, що це те, що він
хотів

6
@WouterH: Насправді, знаючи Фреда, це навряд чи. Він один з тих, хто любить досліджувати темні куточки стандарту C ++ і намагатися зрозуміти його. У певній RPG він вже втратив би всі свої осудні точки;)
Matthieu M.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.