Reputation: 22173
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
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
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