たとえば、次のような宣言:
_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;
のような変数を宣言することは可能ですが、実際にこのような宣言を使用している人はいません。だから私は興味があります-そのような可能性の目的は何ですか?今のところ私はそれが悪名高い「最も厄介な解析」に似たケースを作成するだけで、有用なものは何も追加しないので、
グルーピング。
特定の例として、次のような関数型の変数を宣言できると考えてください。
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
一般に、このような宣言では括弧を使用できます。構文上の観点からの宣言は常に次のように見えるためです。
_<front type> <specification>;
_
たとえば、次の宣言では:
_int* p[2];
_
「フロントタイプ」はint
(_int*
_ではなく)で、「仕様」は_* p[2]
_です。
規則では、「仕様」部分で必要に応じて任意の数の括弧を使用できることがあります。これらの括弧は、明確にすることが避けられない場合があるためです。例えば:
_int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
_
配列へのポインターはまれなケースですが、関数へのポインターを使用した場合と同じ状況です。
_int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
_
これはあなたの質問に対する直接的な答えです。質問がC(y)
のようなステートメントに関するものである場合:
(C(y))
_