11

コンパイラによる括弧の解釈と少し混乱しています。そのような状況で実際に何が起こっているのか説明してもらえますか?

キャスティング:(int)aまたはint(a)

パラメータの受け渡し:

template <typename t>
int size(t (&)[n]){return n;}

明らかに、括弧が意味や解釈を変える多くの異なる文脈が存在する可能性があります。カーテンの後ろで何が起こっているのか正確に説明してもらえますか?コンパイラは、各コンテキストでの解釈方法をどのように知っていますか?一般的なガイドラインはありますか、それとも各ケースに固有のルールですか?

ありがとう

4

3 に答える 3

25

キャプテン衒学者が救助に!

あなたが書くなら

int(value)

これは明示的な型変換として知られているものであり、§5.2.3によって管理されます。正確な言い回しはそれを言います

単純型指定子(7.1.5)の後に括弧で囲まれた式リストが続くと、式リストで指定された型の値が作成されます。式リストが単一の式である場合、型変換式は、対応するキャスト式(5.4)と同等です(定義において、および意味で定義されている場合)。

(私の強調)。つまり、これは

int(value)

(int)value

互いに完全に同一です。これらのうち、書きやすいと思うものを選ぶのはあなた次第です。

2番目の質問ですが、テンプレートと配列を使った例では、あなたが書くつもりだったのはこのようなものだったと思います。

template <typename T, size_t N>
size_t (T (&)[N]) {
    return N;
}

ここにNは、テンプレートパラメータもあります。これを使用すると、コンパイラに配列内の要素の数をT入力させながら、任意の配列を渡すことができます。Nこれが紛らわしいように見える場合(一体何T (&)[N]ですか?)、これはこの関数がタイプのパラメーターを取り込んでいるためですT (&)[N]。これを少し読みやすくするために、次に示すように、このパラメーターに名前を付けましょう。

template <typename T, size_t N>
size_t (T (&array)[N]) {
    return N;
}

これで少し読みやすくなると思います。しかし、この宣言はどういう意味ですか?

T (&array)[N]

これは、正確に要素のsのarray配列への参照であると呼ばれる変数を宣言します。配列へのポインタを宣言できるのと同じように、実際に配列への参照を宣言できます。これは実際にはあまり一般的ではありませんが、この特定のテンプレートイディオムは、配列をテンプレート引数に一致させようとするときに、コンパイラに配列のサイズを推測させる優れた方法です。TN

この場合の括弧の理由は、

T& array[N]

コンパイラはこれを「オブジェクトarrayの配列であると呼ばれる変数であり、それぞれがです。ただし、C ++仕様では参照の配列が特に許可されておらず、これは違法です。括弧はこれを明示的に明確にします。これは関数に似ています。ポインタ-あなたが書くNT&

void (*functionPointer)()

それ以外の

void *functionPointer()

コンパイラに、を返す関数ではなく、ポインタである*ことを意味することを認識させるため。functionPointervoid *

コンパイラがそれぞれの方法で括弧を処理するタイミングを決定する方法に関しては、ルールはかなり複雑であり、実際には、コンパイラが意図した方法で式を解析しない状況がいくつかあります。これらのケースの1つは、口語的に「最も厄介な解析」と呼ばれるもので、コンパイラはオブジェクト構築のように見えるものを関数プロトタイプとして扱います。例として、このコードは次のとおりです。

vector<int> v();

デフォルトのコンストラクターを使用して初期化された呼び出されたものを作成しません。代わりに、これを、引数をとらずに!を生成するという関数の関数プロトタイプとして扱います。しかし、あなたが書くとしたらvector<int>vvvector<int>

vector<int> v(10);

vector<int>次に、コンパイラーは、これがコンストラクター引数としての受け渡しの宣言であると明確に推測できます。これは10、関数プロトタイプとして扱うことができないためです。仕様の§6.8と§8.2は、宣言として扱うことができるものはすべて、関数プロトタイプとして扱うことができるものはすべてそうなると言って、これらのケースを処理します。

配列のコンテキスト(つまり、T (&array)[N])での括弧の場合は、変数を宣言したり、型に明示的な括弧が必要なパラメーターを定義したりするコンテキストでは、あいまいさがないため、別のロジックで処理されます。変数を宣言するために型に名前を付けていることがコンテキストから明らかであるため、意図について。

要約する -

  1. フォームのキャストT(value)(T)value同一です。
  2. の括弧はT (&array)[N]、コンパイラが意図したとおりに&toTではなくtoをバインドしないようにするためのarrayものです。
  3. 括弧の特定の使用は通常、コンテキストから推測されますが、変数宣言と関数プロトタイプの間でいくつかの問題が発生する可能性があります。

お役に立てれば!

于 2011-02-19T08:11:01.937 に答える
5

(int)aまたはint(a)のキャスト

(int)aはキャストです

int(a)は、intのコンストラクタであり、aをintctorに渡します。

式は、演算子の優先順位、アリティ、および演算子が右結合か左結合かに従って評価されます。C++テキストの演算子優先順位チャートを読んでください。

プログラムc++declのコピーを取得します。C ++式を読み取り、式の英語の言語説明を出力します。または、この説明を読んでください。

于 2011-02-19T04:54:01.843 に答える
0

C ++ 14付録Aから、文法に括弧が表示される可能性のあるケースの完全なリストは次のとおりです。

§A.14 Preprocessing directives
control-line: # define identifier lparen identifier-list_opt ) replacement-list new-line
control-line: # define identifier lparen ... ) replacement-list new-line
control-line: # define identifier lparen identifier-list , ... ) replacement-list new-line

§A.2 Lexical conventions
raw-string: " d-char-sequence_opt ( r-char-sequence_opt ) d-char-sequence_opt "

§A.4 Expressions
primary-expression: ( expression )
lambda-declarator: ( parameter-declaration-clause ) mutable_opt exception-specification_opt attribute-specifier-seq_opt trailing-return-type_opt
postfix-expression: const_cast < type-id > ( expression )
postfix-expression: dynamic_cast < type-id > ( expression )
postfix-expression: postfix-expression ( expression-list_opt )
postfix-expression: reinterpret_cast < type-id > ( expression )
postfix-expression: simple-type-specifier ( expression-list_opt )
postfix-expression: static_cast < type-id > ( expression )
postfix-expression: typeid ( expression )
postfix-expression: typeid ( type-id )
postfix-expression: typename-specifier ( expression-list_opt )
unary-expression: alignof ( type-id )
unary-expression: sizeof ( type-id )
unary-expression: sizeof ... ( identifier )
new-expression: ::_opt new new-placement_opt ( type-id ) new-initializer_opt
new-placement: ( expression-list )
new-initializer: ( expression-list_opt )
noexcept-expression: noexcept ( expression )
cast-expression: ( type-id ) cast-expression

§A.5 Statements
selection-statement: if ( condition ) statement
selection-statement: if ( condition ) statement else statement
selection-statement: switch ( condition ) statement
iteration-statement: do statement while ( expression ) ;
iteration-statement: for ( for-init-statement condition_opt ; expression_opt ) statement
iteration-statement: for ( for-range-declaration : for-range-initializer ) statement
iteration-statement: while ( condition ) statement

§A.6 Declarations
static_assert-declaration: static_assert ( constant-expression , string-literal ) ;
decltype-specifier: decltype ( auto )
decltype-specifier: decltype ( expression )
asm-definition: asm ( string-literal ) ;
alignment-specifier: alignas ( assignment-expression ..._opt )
alignment-specifier: alignas ( type-id ..._opt )
attribute-argument-clause: ( balanced-token-seq )
balanced-token: ( balanced-token-seq )

§A.7 Declarators
noptr-declarator: ( ptr-declarator )
parameters-and-qualifiers: ( parameter-declaration-clause ) attribute-specifier-seq_opt cv-qualifier-seq_opt ref-qualifier_opt exception-specification_opt
noptr-abstract-declarator: ( ptr-abstract-declarator )
initializer: ( expression-list )

§A.10 Special member functions
mem-initializer: mem-initializer-id ( expression-list_opt )

§A.11 Overloading
operator-function-id: operator ( )

§A.13 Exception handling
handler: catch ( exception-declaration ) compound-statement
dynamic-exception-specification: throw ( type-id-list_opt )
noexcept-specification: noexcept ( constant-expression )

ご了承ください:

  • プリプロセッサのルールif-groupelif-groupはを参照しconstant-expressionます。
  • lparen(前に空白がないことを意味します
  • のルールraw-stringは字句解析中なので、()はトークンにはなりません。
  • 有効なトークンの任意のシーケンスは、条件がfalseと評価されるプリプロセッサグループに表示される可能性があります。

あなたの質問では、あなたは以下を使用します:

  • cast-expression: ( type-id ) cast-expression
  • postfix-expression: simple-type-specifier ( expression-list_opt )
  • parameters-and-qualifiers: ( parameter-declaration-clause ) attribute-specifier-seq_opt cv-qualifier-seq_opt ref-qualifier_opt exception-specification_opt
  • noptr-abstract-declarator: ( ptr-abstract-declarator )
于 2016-06-02T19:32:25.680 に答える