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.
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.
__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.
__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.
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) |
#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() { }
Standing Document 6 | The official document on Feature Test Recommendations |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/feature_test