std::is_standard_layout
std::is_standard_layout 是 C++11 提供的一个 type traits,用来检查一个类型是否是标准布局的。标准布局的类型是满足以下所有条件的类型:
- 所有非静态成员都是相同的访问权限(public/protected/private)
- 所有非静态成员都没有虚函数、虚基类、非静态成员对象
- 如果有基类,基类也是标准布局
- 成员的顺序没有影响
如果一个类型是标准布局,那么它可以在 C 语言中使用,并且可以用于以下情况:
- 序列化到文件或网络流
- 内存映射文件
- 在多个进程之间共享内存
- 使用
memcpy等函数进行快速复制或移动
可以使用 std::is_standard_layout<T> 来检查一个类型 T 是否是标准布局类型。如果是,它的 value 成员为 true,否则为 false。std::is_standard_layout 可以在编译期确定,可以用于模板元编程中。
std::is_base_of
std::is_base_of<Base, Derived>::value 是一个 constexpr bool 类型的模板变量,用来判断 Derived 类型是否是 Base 类型的派生类。如果是,则 value 为 true,否则为 false。
static_assert(
std::is_base_of<Executor, ExecutorT>::value,
"getKeepAliveToken only works for folly::Executor implementations.");
std::enable_if
std::enable_if 可以在模板实例化时根据模板参数的特性选择模板的某个版本,使得模板的特化程度更加准确,从而避免模板参数错误导致编译错误。
std::enable_if 的语法如下:
template <bool Cond, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> { using type = T; };
其中 Cond 为布尔类型,当 Cond 为 true 时,enable_if 的静态成员变量 type 为 T,否则不定义 type,这使得可以通过 enable_if 进行 SFINAE 技术,即 “Substitution Failure Is Not An Error”,它可以在编译期间进行一些判断和选择,如果判断不符合条件,则会在编译期间被排除,避免出现编译错误。
例如:
template <typename T>
typename std::enable_if<std::is_pointer<T>::value, void>::type
print(T t) {
std::cout << *t << std::endl;
}
int main() {
int a = 10;
int* ptr = &a;
print(ptr); // 输出 10
print(a); // 编译错误,因为 a 不是指针类型
}
在上述代码中,std::enable_if 的第一个参数为 std::is_pointer<T>::value,当 T 是指针类型时,std::is_pointer<T>::value 为 true,此时 std::enable_if 的 type 为 void,因此 print 函数的返回值类型为 void,否则 std::enable_if 的 type 不存在,该函数被排除在外,不会被实例化,从而避免了编译错误。
std::is_convertible
std::is_convertible 是一个 type trait(类型特征),用于判断给定的类型是否可以隐式转换为另一个类型。它的定义如下:
template <class From, class To>
struct is_convertible;
当类型 From 可以隐式转换为类型 To 时,std::is_convertible<From, To>::value 为 true,否则为 false。例如,当 From 是 int,To 是 double 时,std::is_convertible<From, To>::value 将会是 true,因为 int 可以隐式转换为 double。而当 From 是一个函数类型,而 To 是一个指向该函数类型的指针时,也会返回 true。
在实际应用中,std::is_convertible 可以与其他 type trait 结合使用,例如 std::enable_if,用于限制函数模板的参数类型,以便只接受可以隐式转换为目标类型的参数类型。
std::is_same
用于在编译时比较两个类型是否相同。这对于模板编程中的类型检查、静态断言和条件编译非常有用
constexpr bool kAlreadyChecked = std::is_same<KeyT, LookupKeyTNoConst>::value;
if (!kAlreadyChecked) {
checkLegalKeyIfKey(key_new);
}
decltype
decltype 是 C++11 引入的一种关键字,用于查询表达式的类型。它可以在编译时确定变量、函数调用或表达式的类型,并使用该类型进行变量声明、模板参数推导等操作。decltype 提供了一种更简洁、灵活和强大的方式来获取类型信息。
// 1. 推导变量类型
int x = 5;
decltype(x) y = 10; // y 的类型是 int
// 2. 推导表达式类型
int a = 10;
decltype(a + 5) b = 15; // b 的类型是 int,因为 a + 5 的类型是 int
// 3. 推导函数调用返回值
int foo() { return 42; }
decltype(foo()) result = foo(); // result 的类型是 int
// 4. 返回类型后置语法中
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}