19

コードは次のようになります。

struct Foo {
    Foo(const char *);
};

Foo::Foo(const char *str = 0)
{
}

VS 2013 および gcc 4.8.0 はそのようなコードを受け入れますが、clang 3.3 はそのようなコードを次のように拒否します。

エラー: 再宣言にデフォルト引数を追加すると、このコンストラクターがデフォルト コンストラクターになります

標準 (C++03 および C++11) の観点から正しいのは誰ですか?

ノート:

私はclangの選択も気に入っていますが、gccとビジュアルスタジオにバグを報告する予定です。これが標準的な観点から正しくない場合、これはコンパイラの開発者にこの問題を修正するよう説得するのに役立ちます.

GCC

ここで問題を説明しました: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194

しかし運が悪かったので、ドラフトが標準になるまでバグ修正を中断しました。

4

3 に答える 3

12

これはClang メーリングリストで議論されており、欠陥レポートコア問題 1344として提出されています。

メーリングリストの議論から:

アイデアは、特定の特別なメンバーの存在がクラス型のコア プロパティに影響を与えるというものです。たとえば、POD であるか、単純にコピー可能であるかなどです。これらのプロパティを決定するために、プログラム全体の知識は必要ありません。クラス定義からそれらを推測できることが重要です。本当に問題のあるケースは、デフォルト引数を追加して「通常の」コンストラクターをコピーまたは移動コンストラクターに変えることですが、IIRC がデフォルト コンストラクターを導入することも問題でした。

解決策は、コンストラクターの初期宣言にデフォルト引数を入れる必要があることです。

これは、ブルーミントン会議で WG21 によって最後に議論されました。そこからのメモ:

「コンセンサス: 記事で提案されているように、これを不正な形式にします。コアの問題 1344。優先度 0、Doug の起草。」

そのため、CWG は (原則として) これは不適切な形式であるべきであることに同意しました。

TL;DR Clang は、欠陥が修正されるたびに正しい (それが正式に C++14 でのみ発生するのかどうか、またはそのような委員会の決定が C++11 でもさかのぼって行うことができるのかどうかは不明)

于 2013-08-19T12:34:26.053 に答える
1

CLANGが正しいと思います。標準は次のように述べています(標準の古いバージョンと新しいバージョンの両方で12.1.5):

クラス X のデフォルト コンストラクターは、引数なしで呼び出すことができるクラス X のコンストラクターです。

コンストラクターの唯一の引数にデフォルト値を追加すると、引数なしで呼び出すことが確実に可能になり、デフォルト値になります。また、8.3.6には次のように書かれています(強調は私のものです):

デフォルトの引数式は、関数宣言のパラメーター宣言句にのみ指定する必要があります<...>

于 2013-08-19T12:23:26.983 に答える
0

宣言と定義があります。宣言にはデフォルト値がありませんが、定義にはデフォルト値があります。実際、宣言の署名は定義の署名と非常に似ていますが、同じではありません。厳密さは良い考えだと思いますので、宣言と定義を同じにすることを強制する方が良いと思います。

于 2013-08-19T12:23:25.493 に答える