我可以使用带有模板变量的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给我一个编译错误,说“模板参数太少”。
答案 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