关于不完整类型的SFINAE的特殊规则

时间:2017-06-03 04:18:34

标签: c++ templates template-specialization incomplete-type

最近在回答问题if-else depends on whether T is a complete type时,我意识到以下内容无法编译

#include <iostream>
#include <type_traits>

using namespace std;

class Incomplete;
class Complete {};

template <typename IncompleteType>
struct DetermineCompleteHelper : public IncompleteType {};

template <typename IncompleteType, typename = std::enable_if_t<true>>
struct DetermineComplete {
    static constexpr const bool value = false;
};

template <typename IncompleteType>
struct DetermineComplete<IncompleteType, std::enable_if_t<std::is_same<
        decltype(DetermineCompleteHelper<IncompleteType>{}),
        decltype(DetermineCompleteHelper<IncompleteType>{})>::value>> {
    static constexpr const bool value = true;
};

int main() {
    cout << DetermineComplete<Complete>::value << endl;
    cout << DetermineComplete<Incomplete>::value << endl;
    return 0;
}

但是将部分模板专业化更改为

template <typename IncompleteType>
struct DetermineComplete<IncompleteType, std::enable_if_t<std::is_same<
        std::integer_sequence<int, sizeof(IncompleteType)>,
        std::integer_sequence<int, sizeof(IncompleteType)>>::value>> {
    static constexpr const bool value = true;
};

使代码编译没有错误,为什么这种不规则?第一个表达式不应该在部分特化的上下文中被视为错误,因此SFINAE会启动并使类的默认定义成为实例化的吗?

1 个答案:

答案 0 :(得分:3)

尝试实例化DetermineCompleteHelper<IncompleteType>的定义时会发生错误(特别是,它尝试从不完整的基类派生)。这不在眼前。