类型特性
类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。
试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。
定义于<type_traits>头文件的模板可以用不完整类型实例化,除非另外有指定,尽管通常禁止以不完整类型实例化标准库模板。
类型修改
类型修改模板通过应用修改到模板参数,创建新类型定义。结果类型可以通过成员 typedef type 访问。
向给定类型添加左值或右值引用
std::add_lvalue_reference,
std::add_rvalue_reference
template< class T > | (1) | (C++11 起) |
template< class T > | (2) | (C++11 起) |
创建 T
的左值或右值引用类型。
1) 若 T
是对象或无 cv 或引用限定符的函数类型,则提供成员 typedef type
,其为 T&
。若 T
是到某类型 U
的右值引用,则 type
为 U&
。否则, type
为 T
。
2) 若 T
是对象或无 cv 或引用限定符的函数类型,则提供成员 typedef type
,其为 T&&
,否则 type
为 T
。
成员类型
名称 | 定义 |
type | 到 T 的引用,或若不允许则为 T |
辅助类型
template< class T > | (C++14 起) | |
template< class T > | (C++14 起) |
注解
这些类型变换遵从折叠规则:
- std::add_lvalue_reference<T&>::type 是 T&
- std::add_lvalue_reference<T&&>::type 是 T&
- std::add_rvalue_reference<T&>::type 是 T&
- std::add_rvalue_reference<T&&>::type 是 T&&
与直接使用 T& 的主要区别是 std::add_lvalue_reference<void>::type 为 void ,而 void& 导致编译错误。
可能的实现
namespace detail
{
template <class T>
struct type_identity
{
using type = T;
}; // 或使用 std::type_identity (C++20 起)
template <class T>
auto try_add_lvalue_reference(int) -> type_identity<T&>;
template <class T>
auto try_add_lvalue_reference(...) -> type_identity<T>;
template <class T>
auto try_add_rvalue_reference(int) -> type_identity < T&& >;
template <class T>
auto try_add_rvalue_reference(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_lvalue_reference : decltype(detail::try_add_lvalue_reference<T>(0)) {};
template <class T>
struct add_rvalue_reference : decltype(detail::try_add_rvalue_reference<T>(0)) {};
调用示例
#include <iostream>
#include <type_traits>
int main()
{
using nonref = int;
using lref = typename std::add_lvalue_reference<nonref>::type;
using rref = typename std::add_rvalue_reference<nonref>::type;
std::cout << std::boolalpha;
std::cout << "std::is_lvalue_reference<int>::value: "
<< std::is_lvalue_reference<int>::value << std::endl;
std::cout << "std::is_lvalue_reference<std::add_lvalue_reference<nonref>::type>::value: "
<< std::is_lvalue_reference<lref>::value << std::endl;
std::cout << "std::is_rvalue_reference<std::add_rvalue_reference<nonref>::type>::value: "
<< std::is_rvalue_reference<rref>::value << std::endl;
return 0;
}
输出
std::is_lvalue_reference<int>::value: false
std::is_lvalue_reference<std::add_lvalue_reference<nonref>::type>::value: true
std::is_rvalue_reference<std::add_rvalue_reference<nonref>::type>::value: true