なぜこれがデフォルトのコンストラクターを呼び出すのですか?


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)answer); ただし、正しい結果が得られます。
イニシアー2012

2
@JTAそして最後に、X(int(answer));関数宣言であるため、何も出力しません:)
fredoverflow 2012

1
X(answer);なので、何もありません。変数の宣言として解釈できます。その宣言も定義であり、デフォルトのコンストラクターの実行をトリガーします...つまり、自分の質問に答えたことを意味します。
デビッド・ロドリゲス-ドリビアス2012

6
@Daviddouble(expresso);そこに行く、あなたのためだけに宣言;)
fredoverflow 2012

2
@FredOverflow:私は必要としなければならない定義を私は何の効果も感じていないのですから、それを使用する...
デビッド・ロドリゲス- dribeas

回答:


73

X(answer);なので、何もありません。変数の宣言として解釈できます。

あなたの答えはここに隠されています。変数を宣言する場合は、デフォルトのctorを呼び出します(POD以外の場合など)。

編集時:一時的なものを取得するには、いくつかのオプションがあります。


4
static_cast<X>(answer)「ほとんどのC ++」の答えに感じている-それも、古いでお勧めしますGCCのドキュメント右辺値を強制する方法として。
Kerrek SB 2012

ブレース初期化子もコピーが発生する可能性がありますか?
rubenvb 2012

@rubenvb:なぜそうするのですか?これは、新しい言い方でX(answer)あり、ctorの呼び出しを保証します。
xeo 2012

@Xeo:ブレース初期化構文は引数を値で取るためですか?(<-疑問符に注意してください)
rubenvb 2012

4
@KerrekSBしかし、確かにC ++ 11の前だけですよね?これで、正規の答えはになりますX{answer}
Konrad Rudolph

66

括弧はオプションです。あなたが言ったことはと同じX answer;であり、それは宣言文です。


9

タイプXの変数を宣言する場合は、次のようにする必要があります。

X y(answer);

1
彼はそれをX(int)ctorと呼ぶ方法を尋ねなかった。
xeo 2012

ええ、でも私はそれが彼がやろうと思ったことだったと少し感じています:)
huysentruitw 2012

6
@WouterH:実際、フレッドを知っていると、それはありそうにありません。彼は、C ++標準の暗い部分を探索し、それを理解しようとする人々の1人です。特定のRPGでは、彼はすでにすべての正気度ポイントを失っていたでしょう;)
Matthieu M.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.