我有以下代码:
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());
}
此代码适用于使用what方法的一般异常,但有时在我的代码中定义的异常在构造函数中没有任何参数。我需要一种方法来根据父构造函数启用/禁用StackException的构造函数。我如何用SFINAE做到这一点?我正在使用c ++ 11。
答案 0 :(得分:3)
您可以通过std::is_constructible
进行专业化。您必须对整个类进行专门化,不能仅对构造函数进行部分专门化
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
};
但是,您可能会发现,仅复制T
而不是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);
}
答案 1 :(得分:2)
std::is_constructible
是区分大小写所需的特征。
然后,您可以使用SFINAE,专业化或标签分发。
以下示例将标记分派与委托构造函数一起使用:
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() {}
};