How can I conditionally define a default constructor?

I was thinking about a class like:

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

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

    //...
};

I do not think that I can use the constructor template std::enable_iffor this (because there are no arguments). Am I mistaken? If not, is there any other way to do this?

+5
source share
6 answers

C ++ 11 allows you to (reliably) use enable_if-style SFINAE in template arguments:

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 */

In C ++ 03, you could use a unary constructor with a default parameter - the default parameter means that the constructor is still considered the default constructor.

+10
source

You can do something as simple as

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");
    }

    //...
};
+1
source

, , , ( Enabler , ), , - :

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
   }
};
+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>;
};

++ 11, using, .

, , .

0

, . , , .

, (, , , ). . , . . :

#include <string>
template <typename Data>
class Demo
{
    Data d_data;

    public:
        Demo() = default;        // OK when used and Data has a default
                                 // constructor. 

        Demo(Data const &data)   // Exampe of an additional constructor
        :
            d_data(data)
        {}

        // ...
};

struct WithoutDefault
{
    WithoutDefault(int)
    {}
};

int main()
{
    Demo<std::string> withString;
    // Demo<NoDefault> nope;              // won't compile

    WithoutDefault nod(10);
    Demo<WithoutDefault> nodefault(nod);  // OK
}
0

MyClass(){

}
MyClass(int num){

}
MyClass(String s){
}

and you can just write static functions that return a class and write conditions inside:

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

And so on ... Something like this will give you a semi-automatic constructor choice

-1
source

All Articles