禁止 - 継承 コンストラクタ c++



可変的なコンストラクタは暗黙的に生成されたものを隠すことになっていますか? (1)

Variadicコンストラクタは、暗黙的に生成されたコンストラクタ、つまりデフォルトのコンストラクタとコピーコンストラクタを隠すことになっていますか?

struct Foo
{
    template<typename... Args> Foo(Args&&... x)
    {
        std::cout << "inside the variadic constructor\n";
    }
};

int main()
{
    Foo a;
    Foo b(a);
}

何とか私はこの答えを読んだ後に何も印刷しないことを期待していましたが、g ++ 4.5.0でinside the variadic constructor 2回印刷します:(この動作は正しいですか?

バリデーショナルテンプレートなしでも起こります:

struct Foo
{
    Foo()
    {
        std::cout << "inside the nullary constructor\n";
    }

    template<typename A> Foo(A&& x)
    {
        std::cout << "inside the unary constructor\n";
    }
};

int main()
{
    Foo a;
    Foo b(a);
}

再度、両方の行が印刷されます。


暗黙的に宣言されたコピーコンストラクタの宣言は、実際には抑制されていません。 過負荷解決のルールのために呼び出されていないだけです。

暗黙的に宣言されたコピーコンストラクタは、 Foo(const Foo&)という形式です。 これの重要な部分は、const参照を取ることです。 あなたのコンストラクタテンプレートは非const参照をとります。

aはconstではないため、暗黙的に宣言されたコピーコンストラクタよりも非constのユーザ宣言コンストラクタテンプレートが優先されます。 暗黙的に宣言されたコピーコンストラクタを呼び出すにはa constを作ることができます:

const Foo a;
Foo b(a);

またはstatic_castを使用してstatic_castようなconst参照を取得することができます:

Foo a;
Foo b(static_cast<const Foo&>(a));

これを説明する過負荷解決規則は、主にC ++ 0x FCDの13.3.3.2 / 3にあります。 この特定のシナリオは、左辺値と右辺値の組み合わせによって、303ページのさまざまな例で説明されています。

可変長コンストラクタテンプレートはユーザ宣言され、ユーザが宣言したコンストラクタ(C ++ 0x FCD§12.1/ 5)がない場合にのみ暗黙的に宣言されたデフォルトコンストラクタが提供されるため、可変コンストラクタテンプレートは暗黙的に宣言されたデフォルトコンストラクタを抑制します。

クラスXにユーザーが宣言したコンストラクターがない場合、パラメーターを持たないコンストラクターは暗黙的に既定として宣言されます。

varadicコンストラクタテンプレートは、非テンプレートコンストラクタだけがコピーコンストラクタ(C ++ 0x FCD§12.8/ 2,3,8)になる可能性があるため、暗黙的に宣言されたコピーコンストラクタを抑制しません。

クラスX非テンプレートコンストラクタは、最初のパラメータがX&const X&volatile X&const volatile X&いずれかであり、他のパラメータがない場合はコピーコンストラクタです。

クラスX非テンプレートコンストラクタは、その最初のパラメータがX&&const X&&volatile X&& 、またはconst volatile X&&いずれかであり、他のパラメータがない場合、またはデフォルトの引数を持つ場合は移動コンストラクタです。

クラス定義が明示的にコピーコンストラクタを宣言せず、ユーザ宣言された移動コンストラクタがない場合、コピーコンストラクタは暗黙的にデフォルトとして宣言されます。





variadic-templates