类型特性
类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。
试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。
定义于<type_traits>头文件的模板可以用不完整类型实例化,除非另外有指定,尽管通常禁止以不完整类型实例化标准库模板。
类型属性
继承自 std::integral_constant
成员常量
value [静态] | 若 T 为抽象类类型则为 true ,否则为 false(公开静态成员常量) |
成员函数
operator bool | 转换对象为 bool ,返回 value (公开成员函数) |
operator() (C++14) | 返回 value (公开成员函数) |
成员类型
类型 | 定义 |
value_type | bool |
type | std::integral_constant<bool, value> |
检查类型是否为抽象类类型
std::is_abstract
template< class T > | (C++11 起) |
若 T
为抽象类(即声明或继承至少一个纯虚函数的非联合类类型),则提供等于 true 的成员常量 value
。对于其他类型, value
为 false 。
若 T
是非联合类类型,则 T
应为完整类型;否则行为未定义。
模板形参
T | - | 要检查的类型 |
辅助变量模板
template< class T > | (C++17 起) |
调用示例
#include <iostream>
#include <type_traits>
struct A
{
int m;
};
struct B
{
virtual void foo();
};
struct C
{
virtual void foo() = 0;
};
struct D : C {};
int main()
{
std::cout << std::boolalpha;
std::cout << "std::is_abstract<int>::value: "
<< std::is_abstract<int>::value << std::endl;
std::cout << "std::is_abstract<double>::value: "
<< std::is_abstract<double>::value << std::endl;
std::cout << "std::is_abstract<std::string>::value: "
<< std::is_abstract<std::string>::value << std::endl;
std::cout << "std::is_abstract<A>::value: "
<< std::is_abstract<A>::value << std::endl;
std::cout << "std::is_abstract<B>::value: "
<< std::is_abstract<B>::value << std::endl;
std::cout << "std::is_abstract<C>::value: "
<< std::is_abstract<C>::value << std::endl;
std::cout << "std::is_abstract<D>::value: "
<< std::is_abstract<D>::value << std::endl;
return 0;
}
输出
检查类型是否为有符号算术类型
std::is_signed
template< class T > | (C++11 起) |
若 T
是算术类型且 T(-1) < T(0)
,则提供等于 true 的成员常量 value
:这对于浮点类型和有符号整数类型产生 true
,并对无符号整数类型和 bool
类型产生 false
。
对于任何其他类型, value
为 false 。
模板形参
T | - | 要检查的类型 |
辅助变量模板
template< class T > | (C++17 起) |
可能的实现
namespace detail {
template<typename T,bool = std::is_arithmetic<T>::value>
struct is_signed : std::integral_constant<bool, T(-1) < T(0)> {};
template<typename T>
struct is_signed<T,false> : std::false_type {};
} // namespace detail
template<typename T>
struct is_signed : detail::is_signed<T>::type {};
调用示例
#include <iostream>
#include <type_traits>
class A {};
enum B : int {};
enum class C : int {};
int main()
{
std::cout << std::boolalpha;
std::cout << "std::is_signed<A>::value: "
<< std::is_signed<A>::value << std::endl;
std::cout << "std::is_signed<std::string>::value: "
<< std::is_signed<std::string>::value << std::endl;
std::cout << "std::is_signed<float>::value: "
<< std::is_signed<float>::value << std::endl;
std::cout << "std::is_signed<signed int>::value: "
<< std::is_signed<signed int>::value << std::endl;
std::cout << "std::is_signed<unsigned int>::value: "
<< std::is_signed<unsigned int>::value << std::endl;
std::cout << "std::is_signed<B>::value: "
<< std::is_signed<B>::value << std::endl;
std::cout << "std::is_signed<C>::value: "
<< std::is_signed<C>::value << std::endl;
// 简短的形式:
std::cout << "std::is_signed<signed int>(): "
<< std::is_signed<signed int>() << std::endl;
std::cout << "std::is_signed<unsigned int>(): "
<< std::is_signed<unsigned int>() << std::endl;
return 0;
}
输出
检查类型是否为无符号算术类型
std::is_unsigned
template< class T > | (C++11 起) |
若 T
是算术类型且 T(0) < T(-1)
,则提供等于 true 的成员常量 value
:这对无符号整数类型和 bool
类型产生 true
并对有符号整数类型和浮点类型产生 false
。
对于任何其他类型, value
为 false 。
模板形参
T | - | 要检查的类型 |
辅助变量模板
template< class T > | (C++17 起) |
可能的实现
namespace detail {
template<typename T,bool = std::is_arithmetic<T>::value>
struct is_unsigned : std::integral_constant<bool, T(0) < T(-1)> {};
template<typename T>
struct is_unsigned<T,false> : std::false_type {};
} // namespace detail
template<typename T>
struct is_unsigned : detail::is_unsigned<T>::type {};
调用示例
#include <iostream>
#include <type_traits>
class A {};
enum B : int {};
enum class C : int {};
int main()
{
std::cout << std::boolalpha;
std::cout << "std::is_unsigned<A>::value: "
<< std::is_unsigned<A>::value << std::endl;
std::cout << "std::is_unsigned<std::string>::value: "
<< std::is_unsigned<std::string>::value << std::endl;
std::cout << "std::is_unsigned<float>::value: "
<< std::is_unsigned<float>::value << std::endl;
std::cout << "std::is_unsigned<signed int>::value: "
<< std::is_unsigned<signed int>::value << std::endl;
std::cout << "std::is_unsigned<unsigned int>::value: "
<< std::is_unsigned<unsigned int>::value << std::endl;
std::cout << "std::is_unsigned<B>::value: "
<< std::is_unsigned<B>::value << std::endl;
std::cout << "std::is_unsigned<C>::value: "
<< std::is_unsigned<C>::value << std::endl;
// 简短的形式:
std::cout << "std::is_unsigned<signed int>(): "
<< std::is_unsigned<signed int>() << std::endl;
std::cout << "std::is_unsigned<unsigned int>(): "
<< std::is_unsigned<unsigned int>() << std::endl;
return 0;
}