c++ - SFINAE 不适用于 constexpr 函数?

标签 c++ templates c++11 constexpr enable-if

为了支持可移植性,我想选择一个基于事实的常量 size_t是 32 位还是 64 位。 代码:

using namespace std;

namespace detail {
    template<enable_if<is_same<size_t, uint32_t>::value,void*>::type = nullptr>
    constexpr static const size_t defaultSizeHelper() {
        return ( (size_t) 1 << 30 ) / 2 * 5; //2,5 Gb
    }
    template<enable_if<is_same<size_t, uint64_t>::value,void*>::type = nullptr>
    constexpr size_t defaultSizeHelper() {
        return numeric_limits<size_t>::max() / 2;
    }
}

constexpr static size_t defaultSize = detail::defaultSizeHelper();

由于 error: 'std::enable_if<false, void*>::type' has not been declared. template<enable_if<is_same<size_t, uint64_t>::value,void*>::type = nullptr>,此代码无法编译

编译器 - GCC 4.9

在我看来,编译器没有将 SFINAE 原则应用于 constexpr .那我该怎么办呢?

最佳答案

背后的原理SFINAE是如果推导的模板参数的替换导致格式错误的代码,那么该函数模板将从重载决议集中删除,而不是导致硬错误。

在您的情况下,没有推导的模板参数或一个替换,因此您最终会遇到编译错误。你只需要

constexpr static size_t defaultSize = is_same<size_t, uint32_t>::value 
                                        ? (( (size_t) 1 << 30 ) / 2 * 5)
                                        : numeric_limits<size_t>::max() / 2;

出于好奇,如果你想使用 SFINAE,你可以这样做

namespace detail {
    template<typename T, typename enable_if<is_same<T, uint32_t>::value,void*>::type = nullptr>
    constexpr static const T defaultSizeHelper(T) {
        return ( (size_t) 1 << 30 ) / 2 * 5; //2,5 Gb
    }
    template<typename T, typename enable_if<is_same<T, uint64_t>::value,void*>::type = nullptr>
    constexpr T defaultSizeHelper(T) {
        return numeric_limits<size_t>::max() / 2;
    }
}

constexpr static size_t defaultSize = detail::defaultSizeHelper(size_t{});

关于c++ - SFINAE 不适用于 constexpr 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33136815/

相关文章:

c++ - 在编译时将类型转换为整数?

c++ - 重载模板运算符*

c++ - notify_all 不唤醒等待线程

c++ - 使用 std::function 参数重载函数:为什么从未调用 const 方法?

c++ - 一个类可以有多少个构造函数?

c++ - 序列化和反序列化位域

c++ - 如何摆脱 temp 并使用一种转换来完成工作?

C++ — 使用 getch() 的箭头键按下检测莫名其妙地打印了一些单词

c++ - 对模板感到困惑

c++ - 有没有办法在 xcode 上使用 c++0x?我想使用 gcc 4.4 或更高版本