特性测试 (C++20)

来自cppreference.com
< cpp

标准定义一族对应 C++11 或之后引入的 C++ 语言及库特性的预处理器宏。标准有意使之为检测特性是否存在的简单且可移植的方式。

目录

[编辑] 属性

__has_cpp_attribute( attribute-token )

检查属性的存在。

对于标准属性,它将展开成添加属性到工作方案的年和月份(见后述),非官方的属性以非零值确定。

能在 #if#elif 的表达式中展开 __has_cpp_attribute#ifdef#ifndefdefined 把它当做宏,但不能在别处使用。

attribute-token 属性 标准
assert [[assert]] 201806L (C++20)
carries_dependency [[carries_dependency]] 200809L (C++11)
deprecated [[deprecated]] 201309L (C++14)
ensures [[ensures]] 201806L (C++20)
expects [[expects]] 201806L (C++20)
fallthrough [[fallthrough]] 201603L (C++17)
likely [[likely]] 201803L (C++20)
maybe_unused [[maybe_unused]] 201603L (C++17)
no_unique_address [[no_unique_address]] 201803L (C++20)
nodiscard [[nodiscard]] 201603L (C++17)
noreturn [[noreturn]] 200809L (C++11)
unlikely [[unlikely]] 201803L (C++20)

[编辑] 语言特性

下列宏预定义于每个翻译单元。每个宏都展开成对应相应特性包含于工作草案的年与月的整数字面量。

特性显著变更时,宏会相应地更新。

宏名 特性 标准
__cpp_aggregate_bases 扩展聚合初始化 201603L (C++17)
__cpp_aggregate_nsdmi 成员初始化器与聚合体 201304L (C++14)
__cpp_alias_templates 别名模版 200704L (C++11)
__cpp_aligned_new 过对齐数据的动态内存分配 201606L (C++17)
__cpp_attributes 属性 200809L (C++11)
__cpp_binary_literals C++ 核心语言中的二进制字面量 201304L (C++14)
__cpp_capture_star_this [=,*this]*this 的以值 lambda 捕获 201603L (C++17)
__cpp_char8_t char8_t 201811L (C++20)
__cpp_conditional_explicit explicit(bool) 201806L (C++20)
__cpp_constexpr constexpr 200704L (C++11)
放松 constexpr 函数 / constexpr 成员函数上的限制和隐式 const 201304L (C++14)
Constexpr lambda 201603L (C++17)
__cpp_decltype decltype 200707L (C++11)
__cpp_decltype_auto 常规函数的返回类型推导 201304L (C++14)
__cpp_deduction_guides 类模板的模板实参推导 201703L (C++17)
__cpp_delegating_constructors 委托构造函数 200604L (C++11)
__cpp_enumerator_attributes 枚举项的属性 201411L (C++17)
__cpp_fold_expressions 折叠表达式 201603L (C++17)
__cpp_generic_lambdas 泛型(多态) lambda 表达式 201304L (C++14)
__cpp_guaranteed_copy_elision 通过简化值类别保证复制消除 201606L (C++17)
__cpp_hex_float 十六进制浮点字面量 201603L (C++17)
__cpp_if_constexpr constexpr if 201606L (C++17)
__cpp_impl_destroying_delete 销毁的析构函数 operator delete (编译器支持) 201806L (C++20)
__cpp_impl_three_way_comparison 三路比较(编译器支持) 201711L (C++20)
__cpp_inheriting_constructors 继承构造函数 200802L (C++11)
重述继承构造函数 201511L (C++17)
__cpp_init_captures 通用化的 lambda 捕获 201304L (C++14)
__cpp_initializer_lists 初始化器列表 200806L (C++11)
__cpp_inline_variables inline 变量 201606L (C++17)
__cpp_lambdas Lambda 表达式 200907L (C++11)
__cpp_namespace_attributes 命名空间的属性 201411L (C++17)
__cpp_noexcept_function_type 异常规定为类型系统的一部分 201510L (C++17)
__cpp_nontype_template_args 允许全部模板非类型实参的常量求值 201411L (C++17)
__cpp_nontype_template_parameter_auto auto 声明非类型模板形参 201606L (C++17)
__cpp_nontype_template_parameter_class 非类型模板形参中的类类型 201806L (C++20)
__cpp_nsdmi 非静态数据成员初始化器 200809L (C++11)
__cpp_range_based_for 基于范围的 for 循环 200907L (C++11)
通用化基于范围的 for 循环 201603L (C++17)
__cpp_raw_strings 无修饰字符串字面量 200710L (C++11)
__cpp_ref_qualifiers 引用限定符 200710L (C++11)
__cpp_return_type_deduction 常规函数的返回类型推导 201304L (C++14)
__cpp_rvalue_references 右值引用 200610L (C++11)
__cpp_sized_deallocation 具大小解分配 201309L (C++14)
__cpp_static_assert static_assert 200410L (C++11)
扩展 static_assert 201411L (C++17)
__cpp_structured_bindings 结构化绑定 201606L (C++17)
__cpp_template_template_args 模板模板实参的匹配 201611L (C++17)
__cpp_threadsafe_static_init 带并发的动态初始化和析构 200806L (C++11)
__cpp_unicode_characters 新字符类型char16_tchar32_t 200704L (C++11)
__cpp_unicode_literals Unicode 字符串字面量 200710L (C++11)
__cpp_user_defined_literals 用户定义字面量 200809L (C++11)
__cpp_variable_templates 变量模板 201304L (C++14)
__cpp_variadic_templates 变数量参数模板 200704L (C++11)
__cpp_variadic_using using 声明中的包展开 201611L (C++17)

[编辑] 库特性

若包含头文件 <version> 或下表中的对应头文件,则定义下列宏。每个宏都展开成对应相应特性包含于工作草案的年与月的整数字面量。

特性显著变更时,宏会相应地更新。

宏名 特性 头文件 标准
__cpp_lib_addressof_constexpr constexpr std::addressof 201603L <memory> (C++17)
__cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal 201411L <memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_any std::any 201606L <any> (C++17)
__cpp_lib_apply std::apply 201603L <tuple> (C++17)
__cpp_lib_array_constexpr 添加 constexpr 修饰符到 std::reverse_iteratorstd::move_iteratorstd::array容器访问 201603L <iterator> <array> (C++17)
__cpp_lib_as_const std::as_const 201510L <utility> (C++17)
__cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603L <atomic> (C++17)
__cpp_lib_atomic_ref std::atomic_ref 201806L <atomic> (C++20)
__cpp_lib_bind_front std::bind_front <functional> (C++20)
__cpp_lib_bit_­cast std::bit_cast 201806L <bit> (C++20)
__cpp_lib_bool_constant std::bool_constant 201505L <type_traits> (C++17)
__cpp_lib_boyer_moore_searcher 搜索器 (Searcher) 201603L <functional> (C++17)
__cpp_lib_byte 字节类型定义 201603L <cstddef> (C++17)
__cpp_lib_chrono std::chrono::durationstd::chrono::time_point 的舍入函数 201510L <chrono> (C++17)
std::chrono::durationstd::chrono::time_point 的所有成员函数为 constexpr 201611L <chrono> (C++17)
__cpp_lib_chrono_udls 时间类型的用户定义字面量 201304L <chrono> (C++14)
__cpp_lib_clamp 在一对边界值间“夹”着值的算法 (std::clamp) 201603L <algorithm> (C++17)
__cpp_lib_complex_udls std::complex 的用户定义字面量 201309L <complex> (C++14)
__cpp_­lib_­concepts 标准库概念 201806L <concepts> (C++20)
__cpp_­lib_­constexpr_­swap_­algorithms swap 与交换相关函数的 constexpr 201806L <algorithm> (C++20)
__cpp_lib_destroying_delete 销毁的 operator delete (库支持) 201806L <new> (C++20)
__cpp_lib_enable_shared_from_this 再次启用 shared_from_this 201603L <memory> (C++17)
__cpp_lib_exchange_function exchange() 工具函数 201304L <utility> (C++14)
__cpp_lib_execution 执行策略 201603L <execution> (C++17)
__cpp_lib_filesystem 文件系统库 201703L <filesystem> (C++17)
__cpp_lib_gcd_lcm std::gcdstd::lcm 201606L <numeric> (C++17)
__cpp_lib_generic_associative_lookup 添加异相查找到关联容器 201304L <map> <set> (C++14)
__cpp_lib_generic_unordered_lookup 添加异相查找到无序关联容器 <unordered_map> <unordered_set> (C++20)
__cpp_lib_hardware_interference_size constexpr std::hardware_{constructive, destructive}_interference_size 201703L <new> (C++17)
__cpp_lib_has_unique_object_representations std::has_unique_object_representations 201606L <type_traits> (C++17)
__cpp_lib_hypot std::hypot 的 3 参数重载 201603L <cmath> (C++17)
__cpp_lib_incomplete_container_elements 标准容器的最小不完整类型支持 201505L <forward_list> <list> <vector> (C++17)
__cpp_lib_integer_sequence 编译时整数数列 201304L <utility> (C++14)
__cpp_lib_integral_constant_callable std::integral_constant::operator() 201304L <type_traits> (C++14)
__cpp_lib_invoke std::invoke 函数模板 201411L <functional> (C++17)
__cpp_lib_is_aggregate std::is_aggregate 类型特性 201703L <type_traits> (C++17)
__cpp_lib_is_final std::is_final 201402L <type_traits> (C++14)
__cpp_lib_is_invocable std::is_invocablestd::invoke_result 201703L <type_traits> (C++17)
__cpp_lib_is_null_pointer std::is_null_pointer 201309L <type_traits> (C++14)
__cpp_lib_is_swappable [nothrow-]swappable 特性 201603L <type_traits> (C++17)
__cpp_lib_launder 核心问题 1776 :替换含引用成员的类对象 (std::launder) 201606L <new> (C++17)
__cpp_­lib_­list_­remove_­return_­type 更改 std::forward_liststd::listremove()remove_if()unique() 成员的返回类型 201806L <forward_list> <list> (C++20)
__cpp_lib_logical_traits 逻辑运算符类型特性 201510L <type_traits> (C++17)
__cpp_lib_make_from_tuple std::make_from_tuple :对构造应用 201606L <tuple> (C++17)
__cpp_lib_make_reverse_iterator std::make_reverse_iterator 201402L <iterator> (C++14)
__cpp_lib_make_unique std::make_unique 201304L <memory> (C++14)
__cpp_lib_map_try_emplace std::map::try_emplace, std::map::insert_or_assign 201411L <map> (C++17)
__cpp_lib_math_special_functions C++17 的数学特殊函数 201603L <cmath> (C++17)
__cpp_lib_memory_resource std::pmr::memory_resource 201603L <memory_resource> (C++17)
__cpp_lib_node_extract 分割 map 和 set ( std::map::extractstd::map::mergestd::map::insert(node_type) 等) 201606L <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_nonmember_container_access 非成员 size() 和更多类似物(统一容器访问 201411L <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> (C++17)
__cpp_lib_not_fn std::not_fn 201603L <functional> (C++17)
__cpp_lib_null_iterators 向前迭代器 (ForwardIterator) 201304L <iterator> (C++14)
__cpp_lib_optional std::optional 201606L <optional> (C++17)
__cpp_lib_parallel_algorithm 为 C++17 接纳并行 TS 201603L <algorithm> <numeric> (C++17)
__cpp_lib_quoted_string_io std::quoted 201304L <iomanip> (C++14)
__cpp_lib_raw_memory_algorithms 扩展内存管理工具 201606L <memory> (C++17)
__cpp_lib_result_of_sfinae std::result_of 与 SFINAE 201210L <functional> <type_traits> (C++14)
__cpp_lib_robust_nonmodifying_seq_ops 使不修改序列的操作更稳健( std::mismatchstd::equalstd::is_permutation 的双范围重载) 201304L <algorithm> (C++14)
__cpp_lib_sample std::sample 201603L <algorithm> (C++17)
__cpp_lib_scoped_lock 变数量参数 std::lock_guard (std::scoped_lock) 201703L <mutex> (C++17)
__cpp_lib_shared_mutex std::shared_mutex (无时限) 201505L <shared_mutex> (C++17)
__cpp_lib_shared_ptr_arrays std::shared_ptr<T[]> 201611L <memory> (C++17)
__cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606L <memory> (C++17)
__cpp_lib_shared_timed_mutex 重命名 shared_mutexshared_timed_mutex 201402L <shared_mutex> (C++14)
__cpp_lib_string_udls 字符串类型的用户定义字面量 201304L <string> (C++14)
__cpp_lib_string_view std::string_view 201606L <string> <string_view> (C++17)
__cpp_lib_three_way_comparison 三路比较(库支持) 201711L <compare> (C++20)
__cpp_lib_to_chars 初等字符串转换( std::to_charsstd::from_chars 201611L <charconv> (C++17)
__cpp_lib_transformation_trait_aliases 变换特性 (TransformationTrait) 缩略 201304L <type_traits> (C++14)
__cpp_lib_transparent_operators 通透运算符函数对象( std::less<> 等) 201210L <functional> (C++14)
使 std::owner_less 更灵活 (std::owner_less<void>) 201510L <memory> <functional> (C++17)
__cpp_lib_tuple_element_t std::tuple_element_t 201402L <tuple> (C++14)
__cpp_lib_tuples_by_type 以类型寻址 tuple 201304L <utility> <tuple> (C++14)
__cpp_lib_type_trait_variable_templates 类型特性变量模板( std::is_void_v 等) 201510L <type_traits> (C++17)
__cpp_lib_uncaught_exceptions std::uncaught_exceptions 201411L <exception> (C++17)
__cpp_lib_unordered_map_try_emplace std::unordered_map::try_emplacestd::unordered_map::insert_or_assign 201411L <unordered_map> (C++17)
__cpp_lib_variant std::variant : C++17 的类型安全联合体 201606L <variant> (C++17)
__cpp_lib_void_t std::void_t 201411L <type_traits> (C++17)

[编辑] 示例

#ifdef __has_include                           // 检查 __has_include 是否存在
#  if __has_include(<optional>)                // 检查标准库
#    include <optional>
#  elif __has_include(<experimental/optional>) // 检查实验版本
#    include <experimental/optional>
#  elif __has_include(<boost/optional.hpp>)    // 尝试外部库
#    include <boost/optional.hpp>
#  else                                        // 完全找不到
#     error "Missing <optional>"
#  endif
#endif
 
#if __has_cpp_attribute                      // 检查 __has_cpp_attribute 是否存在
#  if __has_cpp_attribute(deprecated)           // 检查属性
#    define DEPRECATED(msg) [[deprecated(msg)]]
#  endif
#endif
#ifndef DEPRECATED
#    define DEPRECATED(msg)
#endif
 
DEPRECATED("foo() has been deprecated") void foo();
 
#if __cpp_constexpr >= 201304                   // 检查特性的指定版本
#  define CONSTEXPR constexpr
#else
#  define CONSTEXPR inline
#endif
 
CONSTEXPR int bar(unsigned i)
{
#ifdef __cpp_binary_literals                    // 检查特性的存在
    unsigned mask1 = 0b11000000;
    unsigned mask2 = 0b00000111;
#else
    unsigned mask1 = 0xA0;
    unsigned mask2 = 0x07;
#endif
    if ( i & mask1 )
        return 1;
    if ( i & mask2 )
        return 2;
    return 0;
}
 
int main()
{
}


[编辑] 参阅

标准文档 6 特性测试推荐上的官方文档