10

私は次のようなクラスを考えていました:

template < typename ...Whatever >
class MyClass
{
public:
    static constexpr bool has_default_ctr = Something;

    // I want this only if "has_default_ctr" is "true".
    MyClass();

    //...
};

コンストラクターテンプレートを使用できるとは思いませんstd::enable_if(引数がないため)。私が間違っている?そうでない場合、これを行う他の方法はありますか?

4

8 に答える 8

16

C++11 ではenable_if、テンプレート引数で -style SFINAEを (確実に) 使用できます。

template<
    // This is needed to make the condition dependent
    bool B = has_default_ctr
    , typename std::enable_if<B, int>::type = 0
>
MyClass();

// When outside of class scope:
// have to repeat the condition for out-of-line definition
template<bool B, typename std::enable_if<B, int>::type = 0>
MyClass::MyClass()
/* define here */

C++03 では、デフォルトのパラメーターを指定して単項コンストラクターを使用できました。デフォルトのパラメーターは、コンストラクターが引き続きデフォルトのコンストラクターとしてカウントされることを意味します。

于 2012-04-25T05:16:24.323 に答える
3

デフォルトのパラメーターを使用したソリューションがコメントに記載されているため、その方法を理解するのにかなりの時間が必要でした (イネーブラー クラスを非公開にしましたが、これは機能しません)。それ:

class MyClass {
public:
   // if constructor is supposed to be public,
   // this helper class must be public as well!
   struct Enabler {}; 

   template <class U = Enabler>
   MyClass (std::enable_if_t<has_default_ctr, U> = Enabler {})
   {
      // whatever
   }
};
于 2015-08-01T10:08:17.107 に答える
1

条件に応じてクラスの異なる定義を取得するには、依存関係の計算をテンプレート引数に入れます。

// primary template, no default constructor unless Something is true
template< typename T, bool has_default_ctr = Something > class MyClass {
    // as you had it, with no default constructor
};

// you want MyClass<T,true> to be just like MyClass<T,false>
// but with a default constructor:
template< typename T > class MyClass<T,true> : public MyClass<T,false> {

    MyClass() : MyClass<T,false>(/* chosen constructor args */) { etc; }

    using MyClass<T,false>::MyClass<T,false>;
};

C++11 がない場合は、usingコンストラクターの継承を使用できず、すべてのコンストラクターを再宣言し、それらの引数を基本クラスに転送する必要があります。

これは指からキーボードへの操作です。私は便利なコンパイラーを持っていないので、マイナーな構文の誤りが多少ありそうです。

于 2012-04-25T05:44:37.740 に答える
0

次のような簡単なことを行うことができます

template < typename ...Whatever >
class MyClass
{
public:
    static constexpr bool has_default_ctr = Something;

    // I want this only if "has_default_ctr" is "true".
    MyClass()
    {
        static_assert(has_default_ctr, "Not Default Constructible");
    }

    //...
};
于 2012-04-25T20:00:18.163 に答える
0

この質問に対する答えは正確ではありません。しかし、その template-parameter-type フィールドにデフォルトのコンストラクターがある場合にのみ、テンプレート クラスのデフォルトのコンストラクターを有効にしたい場合。次に、テンプレート クラスで明示的にデフォルト設定されたコンストラクターを作成するだけです。例を参照してください:

struct HasDefault
{
    HasDefault() = default;
    HasDefault(int) {}
};

struct NoDefault
{
    NoDefault() = delete;
    NoDefault(int) {}
};

template <typename ValueT>
struct Wrapper
{
    Wrapper() = default;
    Wrapper(ValueT &&value) : value(std::forward<ValueT>(value)) {}

    ValueT value;
};

int main()
{
    Wrapper<HasDefault> hasDefault;
    Wrapper<HasDefault> hasDefault2(1);
    //Wrapper<NoDefault> noDefault; error: use of deleted function 'Wrapper<ValueT>::Wrapper()
    Wrapper<NoDefault> noDefault2(1);
}
于 2020-04-28T15:28:48.927 に答える
-1

異なる引数で異なるコンストラクターを使用できます

MyClass(){

}
MyClass(int num){

}
MyClass(String s){
}

そして、クラスを返し、内部に条件を書き込む単純な書き込みおよび静的関数を作成できます。

static chooseContructor(/*parameters*/){
 if(/*something*/){
     return new MyCLass();
 }
 else if(/*something else*/){
     return new MyClass(int num);
 }
 else if{
    return new MyClass(String s);
 }
}

など...そのようなものは、半自動のコンストラクターセレクターを提供します

于 2012-04-25T05:02:50.770 に答える