Feature Test Recommendations (C++20)

From cppreference.com
< cpp

To track progress of partial implementation of C++ standards and experimental features, the feature test recommendations provide a set of preprocessor macros which, if defined by the implementation, give a simple and portable way to detect the presence of said features.

Function Macros

Feature test function macros can be expanded in the expression of #if and #elif. They will be treated as defined macros by #ifdef, #ifndef and defined but cannot be used anywhere else.

Finding Headers

__has_include( header-name ) (1)

Perform a check on the header file name in the same way a #include directive would interpret it.

If the header is found, it expands to 1, 0 otherwise.

Note: __has_include is part of C++17.

Attributes

__has_cpp_attribute( attribute-token )

Checks for the presence of an attribute.

For standard attributes, it will expand to the year and month in which the attribute was added to the working draft, the presence of vendor-specific attributes is determined by a non-zero value.

Language and Library Features

The following macros expand to a numeric value corresponding to the year and month when the feature has been included in the working draft.

When a feature changes significantly, the macro will be updated accordingly.

Macro name Feature Value Header Standard/TS
__cpp_aggregate_bases Extension to aggregate initialization 201603 predefined (C++17)
__cpp_aggregate_nsdmi Member initializers and aggregates 201304 predefined (C++14)
__cpp_alias_templates Template aliases 200704 predefined (C++11)
__cpp_aligned_new Dynamic memory allocation for over-aligned data 201606 predefined (C++17)
__cpp_attributes Attributes 200809 predefined (C++11)
__cpp_binary_literals Binary literals in the C++ core language 201304 predefined (C++14)
__cpp_capture_star_this Lambda capture of *this by value as [=,*this] 201603 predefined (C++17)
__cpp_concepts Constraints and concepts 201507 predefined (concepts TS)
__cpp_constexpr constexpr 200704 predefined (C++11)
Relaxing constraints on constexpr functions / constexpr member functions and implicit const 201304 predefined (C++14)
Constexpr lambda 201603 predefined (C++17)
__cpp_decltype decltype 200707 predefined (C++11)
__cpp_decltype_auto Return type deduction for normal functions 201304 predefined (C++14)
__cpp_deduction_guides Template argument deduction for class templates 201703 predefined (C++17)
__cpp_delegating_constructors Delegating constructors 200604 predefined (C++11)
__cpp_enumerator_attributes Attributes for enumerators 201411 predefined (C++17)
__cpp_exceptions Exception handling 199711 predefined (c++98)
__cpp_explicit_bool explicit(bool) 201806 predefined (c++20)
__cpp_fold_expressions Fold expressions 201603 predefined (C++17)
__cpp_generic_lambdas Generic (polymorphic) lambda expressions 201304 predefined (C++14)
__cpp_guaranteed_copy_elision Guaranteed copy elision through simplified value categories 201606 predefined (C++17)
__cpp_hex_float Hexadecimal floating literals 201603 predefined (C++17)
__cpp_if_constexpr constexpr if 201606 predefined (C++17)
__cpp_inheriting_constructors Inheriting constructors 200802 predefined (C++11)
Rewording inheriting constructors 201511 predefined (C++17)
__cpp_init_captures Generalized lambda-capture 201304 predefined (C++14)
__cpp_initializer_lists Initializer lists 200806 predefined (C++11)
__cpp_inline_variables Inline variables 201606 predefined (C++17)
__cpp_lambdas Lambda expressions 200907 predefined (C++11)
__cpp_lib_addressof_constexpr constexpr std::addressof 201603 <memory> (C++17)
__cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal 201411 <memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_any std::any 201606 <any> (C++17)
__cpp_lib_apply std::apply 201603 <tuple> (C++17)
__cpp_lib_array_constexpr Adding constexpr modifiers to std::reverse_iterator, std::move_iterator, std::array and range access 201603 <iterator> <array> (C++17)
__cpp_lib_as_const std::as_const 201510 <utility> (C++17)
__cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603 <atomic> (C++17)
__cpp_lib_atomic_ref std::atomic_ref 201806 <atomic> (C++20)
__cpp_lib_bit_cast std::bit_cast 201806 <bit> (C++20)
__cpp_lib_bool_constant std::bool_constant 201505 <type_traits> (C++17)
__cpp_lib_boyer_moore_searcher Searchers 201603 <functional> (C++17)
__cpp_lib_byte A byte type definition 201603 <cstddef> (C++17)
__cpp_lib_chrono rounding functions for std::chrono::duration and std::chrono::time_point 201510 <chrono> (C++17)
making all the member functions of std::chrono::duration and std::chrono::time_point constexpr 201611 <chrono> (C++17)
__cpp_lib_chrono_udls User-defined literals for time types 201304 <chrono> (C++14)
__cpp_lib_clamp An algorithm to "clamp" a value between a pair of boundary values (std::clamp) 201603 <algorithm> (C++17)
__cpp_lib_complex_udls User-defined Literals for std::complex 201309 <complex> (C++14)
__cpp_lib_concepts Standard library concepts 201806 <concepts> (C++20)
__cpp_lib_constexpr_swap_algorithms Constexpr for swap and swap related functions 201806 <algorithm> (C++20)
__cpp_lib_enable_shared_from_this Re-enabling shared_from_this 201603 <memory> (C++17)
__cpp_lib_exchange_function exchange() utility function 201304 <utility> (C++14)
__cpp_lib_execution Execution policies 201603 <execution> (C++17)
__cpp_lib_experimental_any class any 201411 <experimental/any> (library fundamentals TS)
__cpp_lib_experimental_apply apply() call a function with arguments from a tuple 201402 <experimental/tuple> (library fundamentals TS)
__cpp_lib_experimental_boyer_moore_searching Extending std::search to use Additional Searching Algorithms 201411 <experimental/functional> (library fundamentals TS)
__cpp_lib_experimental_filesystem File System TS 201406 <experimental/filesystem> (filesystem TS)
__cpp_lib_experimental_function_erased_allocator Type-erased allocator for std::function 201406 <experimental/functional> (library fundamentals TS)
__cpp_lib_experimental_invocation_type Invocation type traits 201406 <experimental/type_traits> (library fundamentals TS)
__cpp_lib_experimental_memory_resources Polymorphic Memory Resources 201402 <experimental/memory_resource> (library fundamentals TS)
__cpp_lib_experimental_optional optional objects 201411 <experimental/optional> (library fundamentals TS)
__cpp_lib_experimental_packaged_task_erased_allocator Type-erased allocator for std::packaged_task 201406 <experimental/future> (library fundamentals TS)
__cpp_lib_experimental_parallel_algorithm Extensions for parallelism 201505 <experimental/algorithm> <experimental/exception_list> <experimental/execution_policy> <experimental/numeric> (parallelism TS)
__cpp_lib_experimental_promise_erased_allocator Type-erased allocator for std::promise 201406 <experimental/future> (library fundamentals TS)
__cpp_lib_experimental_sample sample 201402 <experimental/algorithm> (library fundamentals TS)
__cpp_lib_experimental_shared_ptr_arrays Extending shared_ptr to Support Arrays 201406 <experimental/memory> (library fundamentals TS)
__cpp_lib_experimental_string_view string_view: a non-owning reference to a string 201411 <experimental/string_view> (library fundamentals TS)
__cpp_lib_experimental_type_trait_variable_templates Variable templates For type traits 201402 <experimental/type_traits> (library fundamentals TS)
__cpp_lib_filesystem Filesystem library 201703 <filesystem> (C++17)
__cpp_lib_gcd_lcm std::gcd, std::lcm 201606 <numeric> (C++17)
__cpp_lib_generic_associative_lookup Adding heterogeneous comparison lookup to associative containers 201304 <map> <set> (C++14)
__cpp_lib_hardware_interference_size constexpr std::hardware_{constructive, destructive}_interference_size 201703 <new> (C++17)
__cpp_lib_has_unique_object_representations std::has_unique_object_representations 201606 <type_traits> (C++17)
__cpp_lib_hypot 3-argument overload of std::hypot 201603 <cmath> (C++17)
__cpp_lib_incomplete_container_elements Minimal incomplete type support for standard containers 201505 <forward_list> <list> <vector> (C++17)
__cpp_lib_integer_sequence Compile-time integer sequences 201304 <utility> (C++14)
__cpp_lib_integral_constant_callable std::integral_constant::operator() 201304 <type_traits> (C++14)
__cpp_lib_invoke std::invoke function template 201411 <functional> (C++17)
__cpp_lib_is_aggregate std::is_aggregate type trait 201703 <type_traits> (C++17)
__cpp_lib_is_final std::is_final 201402 <type_traits> (C++14)
__cpp_lib_is_invocable std::is_invocable, std::invoke_result 201703 <type_traits> (C++17)
__cpp_lib_is_null_pointer std::is_null_pointer 201309 <type_traits> (C++14)
__cpp_lib_is_swappable [nothrow-]swappable traits 201603 <type_traits> (C++17)
__cpp_lib_launder Core Issue 1776: Replacement of class objects containing reference members (std::launder) 201606 <new> (C++17)
__cpp_lib_list_remove_return_type Change the return type of the remove(), remove_if() and unique() members of std::forward_list and std::list 201806 <forward_list> <list> (C++20)
__cpp_lib_logical_traits Logical operator type traits 201510 <type_traits> (C++17)
__cpp_lib_make_from_tuple make_from_tuple: apply for construction 201606 <tuple> (C++17)
__cpp_lib_make_reverse_iterator std::make_reverse_iterator 201402 <iterator> (C++14)
__cpp_lib_make_unique std::make_unique 201304 <memory> (C++14)
__cpp_lib_map_try_emplace std::map::try_emplace, std::map::insert_or_assign 201411 <map> (C++17)
__cpp_lib_math_special_functions Mathematical special functions for C++17 201603 <cmath> (C++17)
__cpp_lib_memory_resource std::pmr::memory_resource 201603 <memory_resource> (C++17)
__cpp_lib_node_extract Splicing maps and sets (std::map::extract, std::map::merge, std::map::insert(node_type), etc) 201606 <map> <set> <unordered_map> <unordered_set> (C++17)
__cpp_lib_nonmember_container_access Non-member size() and more (uniform container access) 201411 <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> (C++17)
__cpp_lib_not_fn std::not_fn 201603 <functional> (C++17)
__cpp_lib_null_iterators Null ForwardIterators 201304 <iterator> (C++14)
__cpp_lib_optional std::optional 201606 <optional> (C++17)
__cpp_lib_parallel_algorithm Adopt the Parallelism TS for C++17 201603 <algorithm> <numeric> (C++17)
__cpp_lib_quoted_string_io std::quoted 201304 <iomanip> (C++14)
__cpp_lib_raw_memory_algorithms Extending memory management tools 201606 <memory> (C++17)
__cpp_lib_result_of_sfinae std::result_of and SFINAE 201210 <functional> <type_traits> (C++14)
__cpp_lib_robust_nonmodifying_seq_ops Making non-modifying sequence operations more robust (two-range overloads for std::mismatch, std::equal and std::is_permutation) 201304 <algorithm> (C++14)
__cpp_lib_sample std::sample 201603 <algorithm> (C++17)
__cpp_lib_scoped_lock Variadic std::lock_guard (std::scoped_lock) 201703 <mutex> (C++17)
__cpp_lib_shared_mutex std::shared_mutex (untimed) 201505 <shared_mutex> (C++17)
__cpp_lib_shared_ptr_arrays std::shared_ptr<T[]> 201611 <memory> (C++17)
__cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606 <memory> (C++17)
__cpp_lib_shared_timed_mutex Rename shared_mutex to shared_timed_mutex 201402 <shared_mutex> (C++14)
__cpp_lib_string_udls User-defined literals for string types 201304 <string> (C++14)
__cpp_lib_string_view std::string_view 201606 <string> <string_view> (C++17)
__cpp_lib_to_chars Elementary string conversions (std::to_chars, std::from_chars) 201611 <utility> (C++17)
__cpp_lib_transformation_trait_aliases TransformationTraits Redux 201304 <type_traits> (C++14)
__cpp_lib_transparent_operators Making Operator Functors greater<> 201210 <functional> (C++14)
Making std::owner_less more flexible (std::owner_less<void>) 201510 <memory> <functional> (C++17)
__cpp_lib_tuple_element_t std::tuple_element_t 201402 <tuple> (C++14)
__cpp_lib_tuples_by_type Addressing tuples by type 201304 <utility> <tuple> (C++14)
__cpp_lib_type_trait_variable_templates Type traits variable templates (std::is_void_v, etc) 201510 <type_traits> (C++17)
__cpp_lib_uncaught_exceptions std::uncaught_exceptions 201411 <exception> (C++17)
__cpp_lib_unordered_map_try_emplace std::unordered_map::try_emplace, std::unordered_map::insert_or_assign 201411 <unordered_map> (C++17)
__cpp_lib_variant std::variant: a type-safe union for C++17 201606 <variant> (C++17)
__cpp_lib_void_t std::void_t 201411 <type_traits> (C++17)
__cpp_namespace_attributes Attributes for namespaces 201411 predefined (C++17)
__cpp_noexcept_function_type Make exception specifications be part of the type system 201510 predefined (C++17)
__cpp_nontype_template_args Allow constant evaluation for all non-type template arguments 201411 predefined (C++17)
__cpp_nontype_template_parameter_auto Declaring non-type template parameters with auto 201606 predefined (C++17)
__cpp_nontype_template_parameter_class Class types in non-type template parameters 201806 predefined (C++20)
__cpp_nsdmi Non-static data member initializers 200809 predefined (C++11)
__cpp_range_based_for Range-based for loop 200907 predefined (C++11)
Generalized range-based for loop 201603 predefined (C++17)
__cpp_raw_strings Raw string literals 200710 predefined (C++11)
__cpp_ref_qualifiers ref-qualifiers 200710 predefined (C++11)
__cpp_return_type_deduction Return type deduction for normal functions 201304 predefined (C++14)
__cpp_rtti Run-time type identification (dynamic_cast, typeid) 199711 predefined (c++98)
__cpp_rvalue_references Rvalue reference 200610 predefined (C++11)
__cpp_sized_deallocation Sized deallocation 201309 predefined (C++14)
__cpp_static_assert static_assert 200410 predefined (C++11)
Extended static_assert 201411 predefined (C++17)
__cpp_structured_bindings structured bindings 201606 predefined (C++17)
__cpp_template_template_args Matching of template template-arguments 201611 predefined (C++17)
__cpp_threadsafe_static_init Dynamic initialization and destruction with concurrency 200806 predefined (C++11)
__cpp_transactional_memory Transactional Memory 201505 predefined (TM TS)
__cpp_unicode_characters New character types (char16_t and char32_t) 200704 predefined (C++11)
__cpp_unicode_literals Unicode string literals 200710 predefined (C++11)
__cpp_user_defined_literals User-defined literals 200809 predefined (C++11)
__cpp_variable_templates Variable templates 201304 predefined (C++14)
__cpp_variadic_templates Variadic templates 200704 predefined (C++11)
__cpp_variadic_using Pack expansions in using-declarations 201611 predefined (C++17)

Example

#ifdef __has_include                           // Check if __has_include is present
#  if __has_include(<optional>)                // Check for a standard library
#    include <optional>
#  elif __has_include(<experimental/optional>) // Check for an experimental version
#    include <experimental/optional>
#  elif __has_include(<boost/optional.hpp>)    // Try with an external library
#    include <boost/optional.hpp>
#  else                                        // Not found at all
#     error "Missing <optional>"
#  endif
#endif

#ifdef __has_cpp_attribute                      // Check if __has_cpp_attribute is present
#  if __has_cpp_attribute(deprecated)           // Check for an attribute
#    define DEPRECATED(msg) [[deprecated(msg)]]
#  endif
#endif
#ifndef DEPRECATED
#    define DEPRECATED(msg)
#endif

DEPRECATED("foo() has been deprecated") void foo();

#if __cpp_constexpr >= 201304                   // Check for a specific version of a feature
#  define CONSTEXPR constexpr
#else
#  define CONSTEXPR inline
#endif

CONSTEXPR int bar(unsigned i)
{
#if __cpp_binary_literals                    // Check for the presence of a feature
    unsigned mask1 = 0b11000000;
    unsigned mask2 = 0b00000111;
#else
    unsigned mask1 = 0xC0;
    unsigned mask2 = 0x07;
#endif
    if ( i & mask1 )
        return 1;
    if ( i & mask2 )
        return 2;
    return 0;
}

int main()
{
}


See Also

Standing Document 6 The official document on Feature Test Recommendations