Feature Test Recommendations
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 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 | 201606 | predefined | (C++17) |
Class Template Argument Deduction Assorted NB resolution and issues | 201611 | 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_fold_expressions | Fold expressions | 201411 | predefined | (C++17) |
Unary Folds and Empty Parameter Packs | 201603 | predefined | (C++17) | |
__cpp_generic_lambdas | Generic (Polymorphic) Lambda Expressions | 201304 | predefined | (C++14) |
__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 | Library Fundamentals V1 TS Components: any | 201603 | <any> | (C++17) |
__cpp_lib_apply | Library Fundamentals V1 TS Components: 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_bool_constant | std::bool_constant | 201505 | <type_traits> | (C++17) |
__cpp_lib_boyer_moore_searcher | Library Fundamentals V1 TS Components: 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_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_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 | Filesystem library | 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_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 | Adopt the File System TS for C++17 | 201603 | <filesystem> | (C++17) |
__cpp_lib_gcd | Library Fundamentals V2 Components: std::gcd | 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 | Introduce a 3-Argument Overload to std::hypot | 201603 | <cmath> | (C++17) |
__cpp_lib_incomplete_container_elements | Minimal incomplete type support for standard containers | 201505 | (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_swappable | [nothrow-]swappable traits | 201603 | <type_traits> | (C++17) |
__cpp_lib_is_null_pointer | std::is_null_pointer | 201309 | <type_traits> | (C++14) |
__cpp_lib_launder | Core Issue 1776: Replacement of class objects containing reference members (std::launder) | 201606 | <new> | (C++17) |
__cpp_lib_lcm | Library Fundamentals V2 Components: std::lcm | 201606 | <numeric> | (C++17) |
__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_unique | std::make_unique | 201304 | <memory> | (C++14) |
__cpp_lib_make_reverse_iterator | std::make_reverse_iterator | 201402 | <iterator> | (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 | Library Fundamentals V1 TS Components: 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 | Adopt not_fn from Library Fundamentals 2 for C++17 | 201603 | <functional> | (C++17) |
__cpp_lib_null_iterators | Null ForwardIterator s |
201304 | <iterator> | (C++14) |
__cpp_lib_experimental_parallel_algorithm | Extensions for parallelism | 201505 | <experimental/algorithm> <experimental/exception_list> <experimental/execution_policy> <experimental/numeric> | (parallelism TS) |
__cpp_lib_optional | Library Fundamentals V1 TS Components: optional | 201603 | <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_result_of_sfinae | std::result_of and SFINAE | 201210 | <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 | Library Fundamentals V1 TS Components: 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 | Library Fundamentals V1 TS Components: shared_ptr<T[]> | 201603 | <memory> | (C++17) |
Fixes to shared_ptr support for arrays | 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 | Library Fundamentals V1 TS Components: string_view | 201603 | <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_tuple_element_t | Consistent Metafunction Aliases | 201402 | <utility> | (C++14) |
__cpp_lib_tuples_by_type | Addressing Tuples by Type | 201304 | <utility> | (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_type_trait_variable_templates | Adopt Type Traits Variable Templates from Library Fundamentals TS for C++17 (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_nested_namespace_definitions | Nested namespace definition | 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_nsdmi | Non-static data member initializers | 200809 | predefined | (C++11) |
__cpp_range_based_for | Range-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_auto | Declaring non-type template parameters with auto | 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) |
__lib_cpp_execution | Adopt the Parallelism TS for C++17 | 201603 | <execution> | (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 #endif CONSTEXPR int bar(unsigned i) { #ifdef __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 |