std::make_signed,它接受浮点类型
std::make_signed that accepts floating point types
我有一个模板化的类,它只能为标量类型(整数、浮点等(实例化,并且我希望成员typedef始终是该类型的带符号变体。即:
unsigned int
->signed int
signed long long
->signed long long
(已签名(unsigned char
->signed char
float
->float
long double
->long double
等等。
不幸的是,std::make_signed
只适用于积分类型,而不适用于浮点类型。最简单的方法是什么?我正在寻找using SignedT = ...;
形式的东西,作为我的模板化类的一部分,模板参数T已经保证是标量。
一个简单的模板别名就可以:
#include <type_traits>
template<typename T>
struct identity { using type = T; };
template<typename T>
using try_make_signed =
typename std::conditional<
std::is_integral<T>::value,
std::make_signed<T>,
identity<T>
>::type;
这就是你可以测试它的方法:
int main()
{
static_assert(::is_same<
try_make_signed<unsigned int>::type, int
>::value, "!");
static_assert(std::is_same<
try_make_signed<double>::type, double
>::value, "!");
}
这是一个的实际示例。
在我最初尝试使用std::conditional
时有缺陷后,我决定改用SFINAE。我使用std::enable_if
来有条件地启用浮点类型的专业化:
template<typename T, typename Enable = void>
struct my_make_signed {
typedef typename std::make_signed<T>::type type;
};
template<typename T>
struct my_make_signed<T,
typename std::enable_if<std::is_floating_point<T>::value>::type> {
typedef T type;
};
@jrok最初有可以工作的代码,他只需要做一个小的调整。这是工作代码:
template<typename T>
struct YourClass
{
using SignedT =
typename std::conditional
<
std::is_floating_point<T>::value, //if floating point type
std::common_type<T>, //use it as-is
std::make_signed<T> //otherwise make sure it is signed
>::type::type; //notice the double ::type
};
演示:http://ideone.com/Vw7o82
如果需要多次使用此功能,也可以将上述结构修改为类型特征类。然而,@Andy Prowl的答案是使用别名模板来完成的,这更好。
namespace mine {
template<typename T, bool b>
struct make_signed__ {
typedef T type;
};
template<typename T>
struct make_signed__<T,false> {
typedef typename std::make_signed<T>::type type;
};
template<typename T>
struct make_signed {
typedef typename make_signed__<T, std::is_floating_point<T>::value>::type type;
};
}
int main () {
std::cout << std::is_same<mine::make_signed<unsigned int>::type, int>::value;
std::cout << std::is_same<mine::make_signed<long double>::type, long double>::value;
}
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 尝试在Linux Mint 17.1 64位上"make" C++项目时从cstdlib和类似内容编译错误(未声明/不是类型)
- 如何使用Make以相同的方式编译多个文件类型