Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I conditionally define the default-constructor?

I was thinking of 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 don't think I can use a constructor template and std::enable_if for this (because there's no arguments). Am I wrong? If not, is there some other way to do this?

like image 818
CTMacUser Avatar asked Apr 25 '12 04:04

CTMacUser


2 Answers

C++11 allows 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 have used a unary constructor with a defaulted parameter -- the default parameter means that the constructor still counts as a default constructor.

like image 66
Luc Danton Avatar answered Oct 23 '22 13:10

Luc Danton


Since the solution with a default parameter is mentioned in the comments, but I needed quite some time to figure out how to do it (made my Enabler class private, which does not work), here the suggested solution, in case anybody is looking for it:

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
   }
};
like image 45
JohnB Avatar answered Oct 23 '22 13:10

JohnB