4

次のコードを検討してください。

template<typename T> class Base
{
    Base();
    Base(const Base<T>& rhs);
    template<typename T0> explicit Base(const Base<T0>&  rhs);
    template<typename T0, class = typename std::enable_if<std::is_fundamental<T0>::value>::type> Base(const T0& rhs);
    explicit Base(const std::string& rhs);
};

template<typename T> class Derived : Base<T>
{
    Derived();
    Derived(const Derived<T>& rhs);
    template<class T0> Derived(const T0& rhs) : Base(rhs); 
    // Is there a way to "inherit" the explicit property ?
    // Derived(double) will call an implicit constructor of Base
    // Derived(std::string) will call an explicit constructor of Base
};

同じ明示的/暗黙的プロパティを持つのDerivedすべてのコンストラクターを持つような方法でこのコードを再設計する方法はありますか?Base

4

2 に答える 2

6

C++11はこれを機能として提供します。しかし、GCCでさえ実際にはまだ実装されていません。

実際に実装すると、次のようになります。

template<typename T> class Derived : Base<T>
{
    using Base<T>::Base;
};

そうは言っても、それはあなたの場合には役に立たないかもしれません。継承されたコンストラクターは、オールオアナッシングの命題です。正確にそれらのパラメーターを使用して、すべての基本クラスコンストラクターを取得します。さらに、継承されたものと同じシグニチャを使用してコンストラクタを定義すると、コンパイルエラーが発生します。

于 2012-08-16T16:13:41.423 に答える
2

SFINAEの暗黙的/明示的な構成可能性を検出するには:

template<class T0, typename std::enable_if<
    std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0>
    Derived(const T0& rhs) : Base<T>(rhs) { }
template<class T0, typename std::enable_if<
    std::is_constructible<Base<T>, const T0 &>::value
    && !std::is_convertible<const T0 &, Base<T>>::value, int>::type = 0>
    explicit Derived(const T0& rhs) : Base<T>(rhs) { }

暗黙の兌換性をstd::is_convertibleチェックするという事実を使用し、さらに明示的な兌換性をチェックするために使用します。std::is_constructible

編集:関数シグネチャにないboost::enable_ifのenable_ifソリューションを使用してテンプレートパラメータを修正しました。

チェック:

Derived<int>{5};                            // allowed
[](Derived<int>){}(5);                      // allowed
Derived<int>{std::string{"hello"}};         // allowed
[](Derived<int>){}(std::string{"hello"});   // not allowed
于 2012-08-16T16:51:04.087 に答える