检查父构造函数是否具有参数

时间:2019-03-20 11:01:10

标签: c++ c++11

我有以下代码:

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。

2 个答案:

答案 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() {}
};