41

次のブログを読んだ後:

http://xania.org/200711/ambiguous-overloading

私は、「コンストラクターを常に明示的に定義するべきではないのか?」と自問し始めました。

だから私はこの記事を見つけた以上に読み始めました:

http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/

これは別の例を示し、その背後にある彼の考えも説明しています。もちろん、これはあるブロガーの考えです。

私はあなたの何人かから聞いてうれしいです, 方法についてのあなたの考え, この主題についてのあなたの経験は何ですか, そしてどちらの方法のいくつかの例もいいでしょう.

4

1 に答える 1

63

伝統的な知恵では、1 つのパラメーター (デフォルト パラメーターを使用して明示的または効果的に) を取るexplicitコンストラクターは、変換を定義しない限り、マークする必要があります(後者の 1 つの例std::stringから変換可能)。const char*暗黙の変換が実際に生活を必要以上に困難にする可能性があるという点で、あなたはその理由を自分で理解しました。

おそらく明らかな例外は、コピー コンストラクターです。または、おそらく別の方法は、ほとんどの型がそれ自体との間で変換可能であり、そのためコピー コンストラクターはexplicitほとんどの場合マークされていないことを考慮することです。

他のすべての種類のコンストラクターをマークしても問題ないように見えるかもしれexplicitませんが、私は反対します。whileexplicitは、C++03 では複数の引数を取るコンストラクターには影響しないため、C++11 では効果があります。それをコードに入れるには:

struct foo {
    explicit foo(int i);
    foo(int i, int j);
    explicit foo(int i, int j, int k);
};

foo make_foo()
{
    /* Not C++11-specific: */
    // Error: no conversion from int to foo
    return 42;

    // Okay: construction, not conversion
    return foo(42);

    // Okay: constructions
    return foo(42, 42);
    return foo(42, 42, 42);

    /* C++11 specific: */
    // Error: no conversion from int to foo
    return { 42 };

    // Not an error, not a conversion
    return { 42, 42 };

    // Error! Constructor is explicit
    return { 42, 42, 42 };
    // Not an error, direct-initialization syntax
    return foo { 42, 42, 42 };
}

個人的には、 を返す関数でfoo明示的に return を返す必要があるのは不必要に冗長だと思いますfoo { 42, 42, 42 }。何explicitが私を守っているのかわからない。私は本当に{ initializers... }構文が「指定された初期化子からオブジェクトを構築する」ことを意味することを望んでおりexplicit、何もない状態から私を救いながらその邪魔になります。(結局のところ、コピー初期化のコンテキストで{ i }発生するためi、ほとんどの場合、喜んでそれをあきらめます。)

explicitしたがって、単項コンストラクターに使用する習慣を身につけてください

于 2012-09-15T12:38:26.093 に答える