8

この応答で、tlovelessは、MSVCthis->foo::foo(42); でコンストラクター委任を使用してコンストラクターを直接呼び出すことが可能であることを指摘しました。

#include <iostream>

struct foo
{
    int m;
    foo(int p) : m(p) { std::cout << "foo("<<p<<")\n"; }
    foo()
        : m(0)
    {
        this->foo::foo(42);
        std::cout << "foo(), " << m << "\n";
    }
};

int main()
{
    foo f;
    std::cin.ignore();
}

これが MSVC でもコンパイルできることに驚きました。clang ++、g ++、および私は、それが違法であることに同意します。たとえば、[class.ctor]/2「コンストラクターには名前がないため、名前の検索中に見つかりません」

ただし、MSVC は、MSVC12 Update 1 (2013) および MSVC10 SP1 (2010) の/Wall言語拡張機能の有無にかかわらず警告を発しません。/Za

出力は次のとおりです。

フー(42)
フー()、42

両方のバージョンで。したがって、一時的に作成されるものはありませんが、コンストラクターが呼び出されます。

質問:

  1. この拡張子の名前は何ですか?
  2. 延長とみなされませんか?(/Zaそして拡張機能のリストはそうではないようです)
  3. この機能の / 公式の説明に関するドキュメントはありますか?

(この機能を強く思い出させるので、この質問に [delegating-constructors] タグを付けました)


メタ情報: この機能はある程度知られているため、この質問は重複しているとほぼ確信しています。たとえば、「同様の質問」に対するこの回答を参照してください。この機能を説明する回答が見つかった場合は、これを dup として閉じることを躊躇しないでください。

4

1 に答える 1

1

コンストラクターの委任ではありません。次のコードを試してください:

#include <iostream>

class C{
public:
    C() { std::cout << "C" << std::endl; }
    ~C() { std::cout << "~C" << std::endl; }
};

struct foo
{
    int m;
    C c;
    foo(int p) : m(p) { std::cout << "foo("<<p<<")\n"; }
    foo()
        : m(0)
    {
        this->foo::foo(42);
        std::cout << "foo(), " << m << "\n";
    }
};

int main()
{
    foo f;
}

出力フィールドによると、「c」は 2 回初期化されますが、1 回だけ破棄されます。zneakが指摘したように、これは に似ていnew (this) foo(42)ます。

于 2014-05-08T16:23:59.403 に答える