虽然可以追溯到TR1及boost库中,Type Traits在C++11的标准库中才被C++语言正式引入的。直接地翻译,Type Traits就是“类型的特征”的意思。在C++元编程中,程序员不少时候都需要了解一些类型的特征信息,并根据这些类型信息选择应有的操作。
在《深入理解C++11》一书中,我们就常使用Type Traits来判断类型的特性。比如:
#include
template
constexpr bool is_pod(T) {
return std::is_pod::value;
}
这里就定义了一个名为is_pod的函数模板。该函数模板只是type_traits中模板类is_pod的简单包装。通过该函数,我们可以判断一个类型的数据是否为POD类型的:
int main(){
int a;
std::cout << is_pod(a) << std::endl;
}
int main(){
std::cout << 1 << std::endl;
}
在C++11标准(也是TR1)的提案中(N1424),语言设计者在
Primary type categories |
|
|
|
is_void
(C++11)
|
checks if a type is void |
|
|
is_integral
(C++11)
|
checks if a type is integral type |
|
|
is_floating_point
(C++11)
|
checks if a type is floating-point type |
|
|
is_array
(C++11)
|
checks if a type is an array type |
|
|
is_enum
(C++11)
|
checks if a type is an enumeration type |
|
|
is_union
(C++11)
|
checks if a type is an union type |
|
|
is_class
(C++11)
|
checks if a type is a class type (but not union type) |
|
|
is_function
(C++11)
|
checks if a type is a function type |
|
|
is_pointer
(C++11)
|
checks if a type is a pointer type |
|
|
is_lvalue_reference
(C++11)
|
checks if a type is lvalue reference |
|
|
is_rvalue_reference
(C++11)
|
checks if a type is rvalue reference |
|
|
is_member_object_pointer
(C++11)
|
checks if a type is a pointer to a non-static member object |
|
|
is_member_function_pointer
(C++11)
|
checks if a type is a pointer to a non-static member function |
除去判断类型的特性,
而从实现上讲,这些Type Traits通常是通过模板特化的元编程手段来完成的,比如在g++ 4.8.1的
/// is_const
template
struct is_const
: public false_type { }; // 版本 1
template
struct is_const<_Tp const>
: public true_type { }; // 版本 2
这里的false_type和true_type则是两个helper class,其定义如下:
/// integral_constant
template
struct integral_constant
{
static constexpr _Tp value = __v;
typedef _Tp value_type;
typedef integral_constant<_Tp, __v> type;
constexpr operator value_type() { return value; }
};
template
constexpr _Tp integral_constant<_Tp, __v>::value;
/// The type used as a compile-time boolean with true value.
typedef integral_constant true_type;
/// The type used as a compile-time boolean with false value.
typedef integral_constant false_type;
如果不想细看代码,也可以简单地说,true_type和false_type就是包含一个静态类成员value的类模板,其静态成员一个为true,一个为false,仅此而已。这样一来,通过特化,如果我们使用const类型作为模板is_const类型参数,则可以获得其常量静态成员value的值为true(1)。这是因为模板在实例化的时候选择了“版本2”。反过来,如果模板实例化到“版本1”,则value常量静态成员为false(0)。如下例所示:
#include
#include
int main(){
int a;
const int b = 3;
std::cout << std::is_const::value << std::endl; // 1
std::cout << std::is_const::value << std::endl; // 0
}
/// is_pod
// Could use is_standard_layout && is_trivial instead of the builtin.
template
struct is_pod
: public integral_constant
{ };
这里的__is_pod就是编译器内部的intrinsic。事实上,在C++11中,编译器必须辅助实现很多Type Traits的模板类,C++11标准中这些Type Traits模板类如下所示:
template struct is_class;
template struct is_union;
template struct is_enum;
template struct is_polymorphic;
template struct is_empty;
template struct has_trivial_constructor;
template struct has_trivial_copy;
template struct has_trivial_assign;
template struct has_trivial_destructor;
template struct has_nothrow_constructor;
template struct has_nothrow_copy;
template struct has_nothrow_assign;
template struct is_pod;
template struct is_abstract;
总的来说,Type Traits就是通过元编程的手段,以及编译器的辅助来实现的。