2011-08-19 13 views
13

ここではC++の1日目で学んだことはありますが、これは当然のことですが、標準の文言からはっきりとは分かりません。名前空間スコープのコンストラクタ定義でクラス修飾識別子が必要ですか?

クラス S考える

、我々はそのコンストラクタ

struct S { S(); }; 
S::S() { … } 

を定義することができますが、標準では全く同じように、これを許可しているようだ:常に許可され

struct S { S(); }; 
S() { … } 

自体を持つクラスの名前を予選常に冗長です。たとえば、S::S::S::S() { … }も有効な宣言です。 S::Sの場合、どうして普通ではないのですかS? C++ 11§12.1/ 1から

コンストラクタは名前がありません。特殊な宣言子構文を使用して、コンストラクタを宣言または定義します。構文は、使用しています:

- オプションの各供述指定子は、関数指定子またはconstexprのいずれかがある、供述指定子-seqの、

- コンストラクタのクラス名、および

- パラメータリストを

の順番である。

これは、クラスまたは名前空間のスコープにも等しく適用されます。名前空間の範囲に関する§9.3/ 5の特別な規則があります。

メンバ関数の定義が字句的にクラス定義の外にある場合、メンバ関数名は:: operator 。

しかし、コンストラクタは名前を持っていないので、これは、右は適用されませんか?さらに、構文的なあいまいさがないため、資格を必要とする理由はありません。識別子の戻り値の型およびクラス名で宣言された関数は、現在観察されている規則の下では常に構文エラーです。右?

修飾子を省略してコードを書く必要はありませんが、コンパイラがこれを受け入れる理由はないのでしょうか、それは単に伝統ですか?

+5

あなたは恥ずかしい気がします。私はそれに続く議論に興味があります。 –

+0

誰がこれに-1を与えましたか?なぜ? – Nim

+1

@ニム:誰かが自分の最愛の言葉にしていることを好まないと思う。残念ながら、私の担当者の得点は5の倍数から2になり、私はこの質問に対する答えを受け入れることができます。 – Potatoswatter

答えて

1

名前空間スコープでトークンS() { }に直面したとき、コンパイラは魔法のそれはCTORだ決めることはできません。どの文法規則がそのようなトークンのシーケンスを生成するか?関数定義以外のすべてを無視しましょう。彼らは(){ }部分を生成することはできません。 S()は(§8.4.1参照)宣言子、及び赤緯指定子-配列 OPTが空でなければならなければならないことを意味

。その後、§9.2/ 7は、宣言子は、コンストラクタ、デストラクタ、または変換関数に名前を付ける必要があることを示しています。しかし、Sも名前を付けません。したがって、S() { }は無効です。

+0

9.2/7は "decl-specifier-seqはコンストラクタ、デストラクタ、および変換関数の宣言でのみ省略することができます..."と言っています。したがって、実装はコンストラクタかどうかを確認するために12.1をチェックする必要があります。これはクラスと名前空間のスコープに等しく適用され、 'S'はいずれの場合も同じクラス名です。 – Potatoswatter

+0

@Potatoswatter:はい、コンパイラはこれらの3つのオプションに可能なオプションを制限しています。 '〜'も '演算子'もないので、唯一可能なオプションは本当にctorです。どれ?グローバルスコープでは、 'S'はctorではなくクラスです。 – MSalters

3

はい、それは、メンバ関数の定義は辞書的にそのクラス定義 外のメンバ関数名は、::演算子を使用して、そのクラス名で修飾されなければならないされている場合は

、と述べています。

しかし、それんではないは、そのメンバ関数は、ないは、そのクラス名で修飾されなければならないのw/oの名前言います。それは?;)

実装によっては不確かな領域につながっているようです。ただし、A :: Aの形式は標準によって定義されています。

5.1プライマリ表現クラス名::クラス名が使用され、2つのクラスの名前が同じクラス、この表記名コンストラクタを参照してください

..

A(){..}が許可されているかどうか、私は従来、それを行うには理由がない推測するよう

は(いや、任意のC++コンパイラ私の知る限り??それを許可あり):

  1. コンストラクタは特別なメンバ関数なので、A::A(){..}の方法はほかのメンバ関数と一貫しています。なぜそれが特別な行動を許すのですか?おそらくその努力に値するものではないでしょう。

  2. 標準に明示的に記載されていない規格外のコードを作成する危険性はありません。

+0

これは 'struct S {S();}を禁止しません。 }; S(){...} '。 –

+0

また、式にのみ適用され、12.1/1の構文は宣言子の代わりに使用されます。しかし、私はそれについて知らなかったので、今私は興味があります、コンストラクタに名前を付ける有効な式はありますか? – Potatoswatter

+0

"しかし、名前をつけたメンバー関数はそのクラス名で修飾されてはならないとは言わないよそれは?;)"コンストラクタは資格なしで宣言し定義することができます。 –

関連する問題