• ベストアンサー

C++の規格

デフォルト引数は、関数の宣言部、または定義部の いずれかで与えることができると思うのですが、 VC6sp6で +-------------------------------+ class tmp{ int m_x; public: tmp(int x); }; tmp::tmp(int x=0) : m_x(x){} +-------------------------------+ とすると、「デフォルトコンストラクタがない」と、エラーになります。 (因みにBCC551ではコンパイルできます) また、デフォルトコンストラクタを追加すると、 「オーバーロード関数の呼び出しが解決できない」というエラーになります。 前者のエラーの原因は、コンパイラ エラー C2512を読めば理解できますし、 後者の言うことも納得できます。 ここで疑問です。 (1) デフォルト引数はどこで与えることができるか? (2) デフォルトコンストラクタは、ユーザ定義コンストラクタがある場合は、 必ず用意しなければならないか?(エラーc2512) C++の規格ではどうなっているのでしょうか? よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • meeee
  • ベストアンサー率31% (6/19)
回答No.1

手元にあるのはARMの1版なのですが、ご容赦を。 8.2.6 デフォルト引数は宣言時に指定することが可能です。 #コンパイル結果からは、おっしゃるとおり定義時でも有効になりそうなのですが、記述を見つけられませんでした。 12.1 デフォルトコンストラクタは、コンストラクタが何も宣言されてないときにのみ(必要ならば)生成される。 サンプルソースでは、引数ありのコンストラクタが宣言されていますので、デフォルトコンストラクタは生成されません。 しかし、VC6は定義部のデフォルト引数を有効とみなしたらしく、その結果引数なしの関数が存在し、デフォルトコンストラクタを定義すると、引数なしの関数が2つとなり、オーバーロード関数の呼び出し解決ができなくなったようです。 ARMにも、デフォルト引数を得た結果として、デフォルトコンストラクタとなるということを判断するために、コンパイラに賢くなることを求めている、と記述されていますので、やや賢さが足りなくて、混乱しているのではないでしょうか? BCC551は、定義部のデフォルト引数から、デフォルトコンストラクタ(引数なしのコンストラクタ)が存在すると認識したと予想されます。

その他の回答 (1)

回答No.2

> デフォルト引数は、関数の宣言部、または定義部の > いずれかで与えることができると思うのですが、 違います。 > (1) デフォルト引数はどこで与えることができるか? それを呼ぶ側が知っていなくてはならないので、宣言部です。 > (2) デフォルトコンストラクタは、ユーザ定義コンストラクタがある場合は、必ず用意しなければならないか? いいえ。'必要に応じて' です。

noname#12862
質問者

お礼

デフォルト引数は宣言部で指定する、ということがキモだと思いました。 (2)はアホな質問でした。 インスタンス生成時に、そのインスタンスに対応するコンストラクタがない場合に、C2512のエラーになるということですね。 デフォルトコンストラクタは関係なかったです。 混乱してました。 +-----------------------------+ class tmp{ int m_x; public : tmp(int x = 0); }; tmp::tmp(int x) : m_x(x) { } +-----------------------------+ が正しい記述ですね。 お二方、返事が遅くなりましたが、 ありがとうございました。

関連するQ&A