CppDS.com

C++ 98 11 14 17 20 手册

功能特性测试 (C++20)

来自cppreference.com
< cpp

标准中为 C++11 和其后所引入的 C++ 语言和程序库的功能特性定义了一组预处理器宏。标准有意使之成为检测这些功能特性是否存在的一种简单且可移植的方式。

属性

__has_cpp_attribute( 属性记号 )

检查(宏展开后) 属性记号 所指名的属性的存在。

对于标准属性,它将展开成该属性被添加到工作草案中时的年份和月份(见下表),特定于厂商的属性则以某个非零值确定。

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

属性记号 属性 标准
carries_dependency [[carries_dependency]] 200809L (C++11)
deprecated [[deprecated]] 201309L (C++14)
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)
201907L (C++20)
noreturn [[noreturn]] 200809L (C++11)
unlikely [[unlikely]] 201803L (C++20)

语言功能特性

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

当功能特性发生了显著变更时,宏会相应地更新。

宏名 功能特性 标准
__cpp_aggregate_bases 拥有基类的聚合类 201603L (C++17)
__cpp_aggregate_nsdmi 拥有默认成员初始化器聚合类 201304L (C++14)
__cpp_aggregate_paren_init 形式为直接初始化聚合初始化 201902L (C++20)
__cpp_alias_templates 别名模版 200704L (C++11)
__cpp_aligned_new 过对齐数据的动态内存分配 201606L (C++17)
__cpp_attributes 属性 200809L (C++11)
__cpp_binary_literals 二进制字面量 201304L (C++14)
__cpp_capture_star_this [=,*this] 进行 *this 的按值 lambda 捕获 201603L (C++17)
__cpp_char8_t char8_t 201811L (C++20)
__cpp_concepts 概念 201907L (C++20)
__cpp_conditional_explicit explicit(bool) 201806L (C++20)
__cpp_consteval 立即函数 201811L (C++20)
__cpp_constexpr constexpr 200704L (C++11)
放松 constexpr 函数上的限制和及非 const 的 constexpr 非静态成员函数 201304L (C++14)
Constexpr lambda 201603L (C++17)
constexpr 函数中的平凡默认初始化汇编声明 201907L (C++20)
__cpp_constexpr_dynamic_alloc constexpr 函数中的动态存储期操作 201907L (C++20)
__cpp_constexpr_in_decltype 较不饥渴地实例化 constexpr 函数 201711L (C++20)
__cpp_constinit constinit 201907L (C++20)
__cpp_coroutines 协程 201902L (C++20)
__cpp_decltype decltype 200707L (C++11)
__cpp_decltype_auto 常规函数的返回类型推导 201304L (C++14)
__cpp_deduction_guides 类模板的模板实参推导 201703L (C++17)
聚合体与别名的 CTAD 201907L (C++20)
__cpp_delegating_constructors 委托构造函数 200604L (C++11)
__cpp_designated_initializers 指派初始化器 201707L (C++20)
__cpp_enumerator_attributes 枚举项的属性 201411L (C++17)
__cpp_fold_expressions 折叠表达式 201603L (C++17)
__cpp_generic_lambdas 泛型 lambda 表达式 201304L (C++14)
泛型 lambda 的熟悉模板语法 201707L (C++20)
__cpp_guaranteed_copy_elision 通过简化值类别保证复制消除 201606L (C++17)
__cpp_hex_float 十六进制浮点字面量 201603L (C++17)
__cpp_if_constexpr constexpr if 201606L (C++17)
__cpp_impl_coroutine 协程(编译器支持) 201902L (C++20)
__cpp_impl_destroying_delete 销毁的 operator delete (编译器支持) 201806L (C++20)
__cpp_impl_three_way_comparison 三路比较(编译器支持) 201907L (C++20)
__cpp_inheriting_constructors 继承构造函数 200802L (C++11)
重述继承构造函数 201511L (C++17)
__cpp_init_captures Lambda 初始化捕获 201304L (C++14)
Lambda 初始化捕获中的包展开 201803L (C++20)
__cpp_initializer_lists 列表初始化std::initializer_list 200806L (C++11)
__cpp_inline_variables inline 变量 201606L (C++17)
__cpp_lambdas Lambda 表达式 200907L (C++11)
__cpp_modules 模块 201907L (C++20)
__cpp_namespace_attributes 命名空间的属性 201411L (C++17)
__cpp_noexcept_function_type 异常规定为类型系统的一部分 201510L (C++17)
__cpp_nontype_template_args 允许全部非类型模板实参的常量求值 201411L (C++17)
非类型模板形参中的类类型与浮点类型 201911L (C++20)
__cpp_nontype_template_parameter_auto auto 声明非类型模板形参 201606L (C++17)
__cpp_nsdmi 非静态数据成员初始化器 200809L (C++11)
__cpp_range_based_for 基于范围的 for 循环 200907L (C++11)
拥有相异的 begin/end 类型的基于范围的 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_using_enum using enum 201907L (C++20)
__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 std::reverse_iteratorstd::move_iteratorstd::array范围访问的 constexpr 201603L <iterator> <array> (C++17)
常量表达式迭代器 (ConstexprIterator) std::array 的 constexpr 比较;杂项 constexpr ( std::array::fill 等) 201811L <iterator> <array> (C++20)
__cpp_lib_as_const std::as_const 201510L <utility> (C++17)
__cpp_lib_assume_aligned std::assume_aligned 201811L <memory> (C++20)
__cpp_lib_atomic_flag_test std::atomic_flag::test 201907L <atomic> (C++20)
__cpp_lib_atomic_float 浮点原子类型 201711L <atomic> (C++20)
__cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603L <atomic> (C++17)
__cpp_lib_atomic_lock_free_type_aliases 原子免锁整数类型( std::atomic_signed_lock_freestd::atomic_unsigned_lock_free 201907L <atomic> (C++20)
__cpp_lib_atomic_ref std::atomic_ref 201806L <atomic> (C++20)
__cpp_lib_atomic_shared_ptr std::atomic<std::shared_ptr> 201711L <memory> (C++20)
__cpp_lib_atomic_value_initialization 修正原子初始化(默认值初始化 std::atomic 201911L <atomic> <memory> (C++20)
__cpp_lib_atomic_wait 高效的 std::atomic 等待 201907L <atomic> (C++20)
__cpp_lib_barrier std::barrier 201907L <barrier> (C++20)
__cpp_lib_bind_front std::bind_front 201907L <functional> (C++20)
__cpp_lib_bit_cast std::bit_cast 201806L <bit> (C++20)
__cpp_lib_bitops 位操作 201907L <bit> (C++20)
__cpp_lib_bool_constant std::bool_constant 201505L <type_traits> (C++17)
__cpp_lib_bounded_array_traits std::is_bounded_arraystd::is_unbounded_array 201902L <type_traits> (C++20)
__cpp_lib_boyer_moore_searcher std::boyer_moore_searcher|搜索器 201603L <functional> (C++17)
__cpp_lib_byte std::byte 201603L <cstddef> (C++17)
__cpp_lib_char8_t char8_t 的库支持 201907L <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> (C++20)
__cpp_lib_chrono std::chrono::durationstd::chrono::time_point 的舍入函数 201510L <chrono> (C++17)
std::chrono::durationstd::chrono::time_point 的所有成员函数的 constexpr 201611L <chrono> (C++17)
日历时区 201907L <chrono> (C++20)
__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 标准库概念 202002L <concepts> (C++20)
__cpp_lib_constexpr_algorithms 算法的 constexpr 201806L <algorithm> (C++20)
__cpp_lib_constexpr_complex std::complex 的 constexpr 201711L <complex> (C++20)
__cpp_lib_constexpr_dynamic_alloc std::allocator 与相关工具的 201907L <memory> (C++20)
__cpp_lib_constexpr_functional 杂项 constexpr ( std::default_searcher ); constexpr INVOKE 201907L <functional> (C++20)
__cpp_lib_constexpr_iterator 杂项 constexpr ( std::insert_iterator 等) 201811L <iterator> (C++20)
__cpp_lib_constexpr_memory std::pointer_traits 中的 constexpr 201811L <memory> (C++20)
__cpp_lib_constexpr_numeric <numeric> 算法的 constexpr 201911L <numeric> (C++20)
__cpp_lib_constexpr_string std::string 的 constexpr 201907L <string> (C++20)
__cpp_lib_constexpr_string_view 杂项 constexpr ( std::string_view::copy 201811L <string_view> (C++20)
__cpp_lib_constexpr_tuple 杂项 constexpr ( std::tuple::operator= 等) 201811L <tuple> (C++20)
__cpp_lib_constexpr_utility 杂项 constexpr ( std::pair::operator= 等) 201811L <utility> (C++20)
__cpp_lib_constexpr_vector std::vector 的 constexpr 201907L <vector> (C++20)
__cpp_lib_coroutine 协程(库支持) 201902L <coroutine> (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_endian std::endian 201907L <bit> (C++20)
__cpp_lib_erase_if 统一容器擦除 202002L <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++20)
__cpp_lib_exchange_function std::exchange 201304L <utility> (C++14)
__cpp_lib_execution 执行策略 201603L <execution> (C++17)
std::execution::unsequenced_policy 201902L <execution> (C++20)
__cpp_lib_filesystem 文件系统库 201703L <filesystem> (C++17)
__cpp_lib_format 文本格式化 201907L <format> (C++20)
__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 无序关联容器中的异质比较查找 201811L <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_int_pow2 整数的 2 的幂运算std::has_single_bitstd::bit_ceilstd::bit_floorstd::bit_length 202002L <bit> (C++20)
__cpp_lib_integer_comparison_functions 整数比较函数 202002L <utility> (C++20)
__cpp_lib_integer_sequence 编译时整数序列 201304L <utility> (C++14)
__cpp_lib_integral_constant_callable std::integral_constant::operator() 201304L <type_traits> (C++14)
__cpp_lib_interpolate std::lerpstd::midpoint 201902L <cmath> <numeric> (C++20)
__cpp_lib_invoke std::invoke() 201411L <functional> (C++17)
__cpp_lib_is_aggregate std::is_aggregate 201703L <type_traits> (C++17)
__cpp_lib_is_constant_evaluated std::is_constant_evaluated 201811L <type_traits> (C++20)
__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_layout_compatible std::is_layout_compatible 201907L <type_traits> (C++20)
__cpp_lib_is_nothrow_convertible std::is_nothrow_convertible 201806L <type_traits> (C++20)
__cpp_lib_is_null_pointer std::is_null_pointer 201309L <type_traits> (C++14)
__cpp_lib_is_pointer_interconvertible 指针可互转换特征 201907L <type_traits> (C++20)
__cpp_lib_is_swappable [nothrow-]swappable 特征 201603L <type_traits> (C++17)
__cpp_lib_jthread 停止记号结合线程 201911L <stop_token> <thread> (C++20)
__cpp_lib_latch std::latch 201907L <latch> (C++20)
__cpp_lib_launder 核心问题 1776 :替换含引用成员的类对象( std::launder 201606L <new> (C++17)
__cpp_lib_list_remove_return_type 更改 std::forward_liststd::list remove()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_constants 数学常数 201907L <numbers> (C++20)
__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 std::size()std::data()std::empty() 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 遗留向前迭代器 (LegacyForwardIterator) 201304L <iterator> (C++14)
__cpp_lib_optional std::optional 201606L <optional> (C++17)
__cpp_lib_parallel_algorithm 并行算法 201603L <algorithm> <numeric> (C++17)
__cpp_lib_polymorphic_allocator std::polymorphic_allocator<> 作为词汇类型 201902L <memory> (C++20)
__cpp_lib_quoted_string_io std::quoted 201304L <iomanip> (C++14)
__cpp_lib_ranges 范围库受约束算法 201911L <algorithm> <functional> <iterator> <memory> <ranges> (C++20)
__cpp_lib_raw_memory_algorithms 扩展内存管理工具 201606L <memory> (C++17)
__cpp_lib_remove_cvref std::remove_cvref 201711L <type_traits> (C++20)
__cpp_lib_result_of_sfinae std::result_of 与 SFINAE 201210L <type_traits> <functional> (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::scoped_lock 201703L <mutex> (C++17)
__cpp_lib_semaphore std::counting_semaphorestd::binary_semaphore 201907L <semaphore> (C++20)
__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)
std::make_shared 的数组支持 201707L <memory> (C++20)
__cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606L <memory> (C++17)
__cpp_lib_shared_timed_mutex std::shared_timed_mutex 201402L <shared_mutex> (C++14)
__cpp_lib_shift std::shift_leftstd::shift_right 201806L <algorithm> (C++20)
__cpp_lib_smart_ptr_for_overwrite 用默认初始化创建智能指针( std::allocate_shared_for_overwritestd::make_shared_for_overwritestd::make_unique_for_overwrite 201811L <memory> (C++20)
__cpp_lib_source_location 源码信息捕获( std::source_location 201907L <source_location> (C++20)
__cpp_lib_span std::span 202002L <span> (C++20)
__cpp_lib_ssize std::ssize 与无符号的 std::span::size 201902L <iterator> (C++20)
__cpp_lib_starts_ends_with 字符串前缀与后缀检查( std::stringstd::string_viewstarts_with()ends_with() 201711L <string> <string_view> (C++20)
__cpp_lib_string_udls 字符串类型的用户定义字面量 201304L <string> (C++14)
__cpp_lib_string_view std::string_view 201606L <string> <string_view> (C++17)
常量表达式迭代器 (ConstexprIterator) 201803L <string> <string_view> (C++20)
__cpp_lib_syncbuf 201803L <syncstream> (C++20)
__cpp_lib_three_way_comparison 三路比较(库支持);添加三路比较到标准库 201907L <compare> (C++20)
__cpp_lib_to_address 转换指针为裸指针( std::to_address 201711L <memory> (C++20)
__cpp_lib_to_array std::to_array 201907L <array> (C++20)
__cpp_lib_to_chars 初等字符串转换( std::to_charsstd::from_chars 201611L <charconv> (C++17)
__cpp_lib_transformation_trait_aliases 变换特征的别名模板 201304L <type_traits> (C++14)
__cpp_lib_transparent_operators 通透运算符函数对象( std::less<> 等) 201210L <functional> (C++14)
通透的 std::owner_lessstd::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 <tuple> <utility> (C++14)
__cpp_lib_type_identity std::type_identity 201806L <type_traits> (C++20)
__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_unwrap_ref std::unwrap_ref_decaystd::unwrap_reference 201811L <functional> (C++20)
__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()
{
}


参阅

关闭