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;
}