15

重複の可能性:
条件で定義された変数を引数で構成できないのはなぜですか?

次の簡単な例を考えてみましょう。

/*1*/ int main() {
/*2*/   for (int i(7); i;){break;} 
/*3*/   if (int i(7)) {}
/*4*/ }

行 2 は正常にコンパイルされるのに、行 3 ではエラーが発生するのはなぜですか? これは、この側面で if ステートメントが for ループよりも扱いが悪いのはなぜか、私には少し奇妙です。

これがコンパイラ固有の場合 - gcc-4.5.1でテストしました:

prog.cpp: 関数 'int main()' 内: prog.cpp:3:7: エラー: 'int' の前にプライマリ式が必要です prog.cpp:3:7: エラー: 'int' の前に ')' が必要です

私はこの質問に触発されました

[アップデート]

私はこれがうまくコンパイルされることを知っています:

/*1*/ int main() {
/*2*/   for (int i = 7; i;){break;} 
/*3*/   if (int i = 7) {}
/*4*/ }

[更新2]

std::unique_ptr<>これは純粋に学術的な質問のようですが、これはコピーできないタイプの場合、非常に重要になる可能性があります。

#include <memory>
int main() {
  if (std::unique_ptr<int> i = new (std::nothrow) int(7)) {
  }
  if (std::unique_ptr<int> i(new (std::nothrow) int(7))) {
  }
}

これら 2 種類のいずれも許可されません。新しい C++11 構文についてよくわかりませんか{}?

4

2 に答える 2

11

C++ 標準は根拠を提供していませんが、コンストラクター表記を使用すると矛盾が生じる可能性があると思います。たとえば、関数宣言はifステートメントで許可されていないため、最も面倒な解析は実際には意図したことを意味します。例えば:

int f();        // function declaration (simple form or the most vexing parse)
if (int f()) {  // illegal in C++ but, when allowed, would be a zero-initialized int
}

C++ 2011 では、ブレースの初期化を使用できます。

if (int x{f()}) {
    ...
}

残念ながら、ブレース初期化は、コンストラクター表記を使用することと常に同じことを意味するとは限りません (直接初期化と呼ばれると思います)。

更新に関しては、次のいずれかを使用できます。

if (std::unique_ptr<int> p = std::unique_ptr<int>(new int(1))) { ... }
if (auto p = std::unique_ptr<int>(new int(2))) { ... }
if (std::unique_ptr<int>{new int(3)}) { ... }

たくさんのオプションがあるようです:-)

于 2012-09-29T21:41:16.080 に答える
2

構文に関しては、理由は簡単です。

ステートメントの最初の要素forステートメントです。ステートメントは、変数を作成するだけでなく、変数を初期化することもできます。if条件は条件です=仕様は、条件が変数を作成できることを定義していますが、初期化によってのみです。

この仕様では、変数を作成することさえ許可されていることをうれしく思いifます。それを可能にする特別な文法が必要であり (「条件」は「式」とは異なります)、それはおそらく C から継承されたものでした。

そうは言っても、C++ 11 では、宣言を波括弧初期化リスト(「初期化子リスト」の仕様について言えば) で初期化できる条件が定義されています。だから、それは合法であるべきです。しかし、VS2012 はまだイニシャライザ リストをサポートしていないため...

于 2012-09-29T22:14:27.453 に答える