如何在模板中同时允许浮点数和整数类型但不允许 bool
How can I allow both floating-point and integer types but disallow bool in a template
假设我有一些数字 class,带有一个允许“数字”(故意引号)的构造函数。
在内部,它存储为一个浮点值,所以我只想要一个数字作为参数,所以我拒绝对除浮点数以外的其他类型进行实例化:
template<typename T>
struct MyClass
{
MyClass( T value ) : _v(value)
{
static_assert( std::is_floating_point<T>::value, "only numbers!" );
}
double _v;
};
然而,这很烦人,因为我总是要写 MyClass m(42.);
,有时我会忘记,或者其他什么,我希望能够只写 MyClass m(42);
。
所以我添加了整数类型:
template<typename T>
struct MyClass
{
MyClass( T value ) : _v(value)
{
static_assert( std::is_floating_point<T>::value || std::is_integral<T>::value, "only numbers!" );
}
double _v;
};
这样做的缺点是 std::is_integral 也允许 bool
。
而且我觉得允许从布尔值自动转换为数值完全是胡说八道(当然是在那种情况下)。
MyClass m(true); // no way !
问题:如何允许浮点数和整数类型,而禁用布尔类型? (没有 std::is_boolean
可用)
您可以用 std::is_same
检查 bool
。例如
MyClass( T value ) : _v(value)
{
static_assert( ( std::is_floating_point<T>::value ||
std::is_integral<T>::value ) &&
!std::is_same<T, bool>::value, "only numbers!" );
}
在我看来,最简单的方法是模板构造函数 + bool
的显式删除构造函数。看看这个 - 它非常明确并且可以做你想做的事:
#include <type_traits>
template<typename T>
struct MyClass
{
template<class U>
MyClass(U value) : _v(value)
{
}
MyClass(bool) = delete;
double _v;
};
int main() {
auto foo = MyClass<double>(3);
auto bar = MyClass<int>(1);
auto baz = MyClass<double>(true); // fails
}
假设我有一些数字 class,带有一个允许“数字”(故意引号)的构造函数。 在内部,它存储为一个浮点值,所以我只想要一个数字作为参数,所以我拒绝对除浮点数以外的其他类型进行实例化:
template<typename T>
struct MyClass
{
MyClass( T value ) : _v(value)
{
static_assert( std::is_floating_point<T>::value, "only numbers!" );
}
double _v;
};
然而,这很烦人,因为我总是要写 MyClass m(42.);
,有时我会忘记,或者其他什么,我希望能够只写 MyClass m(42);
。
所以我添加了整数类型:
template<typename T>
struct MyClass
{
MyClass( T value ) : _v(value)
{
static_assert( std::is_floating_point<T>::value || std::is_integral<T>::value, "only numbers!" );
}
double _v;
};
这样做的缺点是 std::is_integral 也允许 bool
。
而且我觉得允许从布尔值自动转换为数值完全是胡说八道(当然是在那种情况下)。
MyClass m(true); // no way !
问题:如何允许浮点数和整数类型,而禁用布尔类型? (没有 std::is_boolean
可用)
您可以用 std::is_same
检查 bool
。例如
MyClass( T value ) : _v(value)
{
static_assert( ( std::is_floating_point<T>::value ||
std::is_integral<T>::value ) &&
!std::is_same<T, bool>::value, "only numbers!" );
}
在我看来,最简单的方法是模板构造函数 + bool
的显式删除构造函数。看看这个 - 它非常明确并且可以做你想做的事:
#include <type_traits>
template<typename T>
struct MyClass
{
template<class U>
MyClass(U value) : _v(value)
{
}
MyClass(bool) = delete;
double _v;
};
int main() {
auto foo = MyClass<double>(3);
auto bar = MyClass<int>(1);
auto baz = MyClass<double>(true); // fails
}