变量模板和std :: enable_if

时间:2016-04-15 22:03:21

标签: c++ enable-if variable-templates

我可以使用带有模板变量的enable_if(或者是否有一些替代技术可用)。 e.g。

typedef float Float;
typedef double Double;

template<class T>
constexpr Bool IsFloat = std::is_same_v<T, Float>;

template<class T>
constexpr Bool IsDouble = std::is_same_v<T, Double>;

template<class T>
constexpr Bool IsFloatingPoint = IsFloat<T> || IsDouble<T>;

template<class T>
using EnableIfFloatingPoint = std::enable_if_t<IsFloatingPoint<T>>;

template
<
    class T,
    typename = EnableIfFloatingPoint<T>
>
constexpr T Pi = T(3.1415926535897932384626433832795);

当我尝试使用Pi<float>时,Visual Studio给我一个编译错误,说“模板参数太少”。

1 个答案:

答案 0 :(得分:3)

立即开始我建议使用std::is_floating_point而不是手动滚动自己的浮点检测机制。此外,从C ++ 17开始,您将能够使用_v后缀而不是::value

正如在一些评论中提到的,在变量模板上使用SFINAE本身并没有多大意义,但是你可以实现只允许浮点类型能够采用{{{{{ 1}}通过尝试将变量模板设置为类型Pi,如果条件满足,当然只有推导类型。

std::enable_if_t< std::is_floating_point<T>::value, T>
对于整数类型template<class T> using EnableIfFloatingPoint = std::enable_if_t<std::is_floating_point<T>::value, T>; template<class T> constexpr T Pi = EnableIfFloatingPoint<T>(3.1415926535897932384626433832795);

Pi<T>将无法编译,因为 T没有推断出任何类型,但我不会考虑这个SFINAE。

更好的解决方案是使用EnableIfFloatingPoint<T>函数模板,其中包含相应的constexpr消息,该消息验证模板是使用&#34;更正&#34;来实例化的。类型。

static_assert