greywolf82
greywolf82

Reputation: 22173

Check if parent constructor has parameters

I have got this code:

template<class T>
class StackException: public T {
    public:
        StackException(const char* msg): T(msg) {} //<---problem here
}

template<class T>
void myThrow(const &T e) {
    throw StackException<T>(e.what());
}

This code works for generic exceptions with a what method, but sometimes the exceptions in my code are defined without any parameter in the constructor. I need a way to enable/disable the constructor of StackException according to the parent constructor. How can I do that with SFINAE? I'm using c++11.

Upvotes: 2

Views: 93

Answers (2)

Jarod42
Jarod42

Reputation: 217398

std::is_constructible is the traits you need to differentiate the case. You might then use SFINAE, specialization or tag dispatching.

Following example use tag dispatching with delegate constructor:

template<class T>
class StackException: public T {
public:
    StackException(const char* msg) :
         StackException(msg, std::is_constructible<T, const char *>{})
    {}

private:
    StackException(const char* msg, std::true_type): T(msg) {}
    StackException(const char* msg, std::false_type): T() {}
};

Upvotes: 2

Caleth
Caleth

Reputation: 62719

You can specialise via std::is_constructible. You'll have to specialise the whole class, you can't partially specialise just the constructor

template<class T, class = std::is_constructible<T, const char *>>
class StackException;

template<class T>
class StackException<T, std::true_type> : public T {
public:
    StackException(const char* msg): T(msg) {} // no problem anymore
};

template<class T>
class StackException<T, std::false_type> : public T {
public:
    StackException(const char* msg): {} // no problem anymore
};

However you may find that it's easier to just copy the T, rather than it's what

template<class T>
class StackException : public T {
public:
    StackException(const T & t): T(t) {} // no problem anymore
};

template<class T>
void myThrow(const &T e) {
    throw StackException<T>(e);
}

Upvotes: 3

Related Questions