1. ホーム
  2. c++

[解決済み] なぜC++では変数を宣言するときに変数名を括弧で囲むことができるのですか?

2023-05-10 13:18:38

疑問点

例えばこんな宣言があります。

int (x) = 0;

あるいはそれすらも

int (((x))) = 0;

私がこれを偶然見つけたのは、私のコードの中に、たまたま次のような断片があったためです。

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}

明らかに、私はオブジェクト C を構築し、そのデストラクタで何か役に立つことをしたかったのです。しかし、コンパイラは C (y); を変数の宣言として扱います。 y という型を持つ C というエラーが表示され、そのため y の再定義に関するエラーを表示します。面白いのは、もし私がこれを C (y).f () のように書くか C (static_cast<B*> (y)) のようにすると、意図したとおりにコンパイルされます。現代的な回避策としては {} を使うことです。

で、その後にわかったことですが、変数の宣言に int (x) = 0; とか、あるいは int (((x))) = 0; でも、実際にこのような宣言を使用している人を見たことがありません。今のところ、悪名高い "most vexing parse" に似たケースを作成するだけで、何も有用なものを追加しないことがわかりますので、私は興味があります。

どのように解決するのですか?

グループ化する。

具体的な例として、次のような関数型の変数を宣言することを考えてみましょう。

int f(int);

さて、このようなものへのポインタはどのように宣言するのでしょうか?

int *f(int);

いや、うまくいかない! これは、以下のような関数を返すと解釈されます。 int* . 正しい方法でパースするためには、括弧を追加する必要があります。

int (*f)(int);

配列と同じ扱いです。

int *x[5];   // array of five int*
int (*x)[5]; // pointer to array of five int