4

C++11 では、コンストラクターを継承できるため、特にラッパー クラスのようなもので、多くのボイラープレートを回避できます。ただし、可変個引数テンプレートだけでこの機能をすでに実現できているようです。

class B
{
public:
 B(int){//do something}
 B(int, char){//do something}
};

継承コンストラクターの使用:

class D : public B
{
public:
 using B::B; 
};

可変個引数テンプレートと転送の使用:

class D : public B
{
public:
 template <typename...Args>
 D(Args&&... args) : B(std::forward<Args>(args)...)
 {
 }
};

一貫性 (コンストラクターとメソッドを同じように扱うusing) と使いやすさは、継承されたコンストラクターを言語に組み込む非常に良い理由ですが、最初のソリューションが 2 番目のソリューションよりも優先される理由は他にありますか? CWG ドキュメント ( N1890N1898 ) の両方で、コンストラクターの継承について議論しているのを見つけました。

これを使用して、通常のメンバー関数だけでなくコンストラクターでも機能することを妨げているのは、歴史的な事故にすぎません。コンストラクターがクラスの名前で参照されるのではなく、「ctor」または「constructor」と呼ばれていれば、これは機能していたでしょう。これをコンストラクタ継承の仕組みとして提案します。

4

3 に答える 3

2

メンテナンスの問題 (コンパイラ エラー) により、「使用」が優先される場合があります。

struct Base
{
    Base(int) {}
};

struct Derived : public Base
{
    using Base::Base;
};

struct DerivedTemplate : Base
{
    template <typename...Args>
    DerivedTemplate(Args&&... args)
    : Base(std::forward<Args>(args)...)
    {}
};

int main()
{
    // error: no matching function for call to ‘Derived::Derived(int, int)’
    Derived d(1, 2);

    // In instantiation of ‘DerivedTemplate::DerivedTemplate(Args&& ...) [with Args = {int, int}]’:
    // required from here
    // error: no matching function for call to ‘Base::Base(int, int)’
    DerivedTemplate dt(1, 2);
}

また、各テンプレートのインスタンス化は異なるコンストラクターです (使用しても乗算されません)。

于 2015-01-14T20:11:48.063 に答える