Feature Test Recommendations


To track progress of partial implementation of C++ standards and experimantal 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.


[edit] 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.

[edit] 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.

[edit] 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.

[edit] 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_nsdmi Member initializers and aggregates 201304 predefined (C++14)
__cpp_alias_templates Template aliases 200704 predefined (C++11)
__cpp_attributes Attributes 200809 predefined (C++11)
__cpp_binary_literals Binary Literals in the C++ Core Language 201304 predefined (C++14)
__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)
__cpp_decltype decltype 200707 predefined (C++11)
__cpp_decltype_auto Return type deduction for normal functions 201304 predefined (C++14)
__cpp_delegating_constructors Delegating Constructors 200604 predefined (C++11)
__cpp_exceptions Exception handling 199711 predefined (c++98)
__cpp_generic_lambdas Generic (Polymorphic) Lambda Expressions 201304 predefined (C++14)
__cpp_inheriting_constructors Inheriting Constructors 200802 predefined (C++11)
__cpp_init_captures Generalized Lambda-capture 201304 predefined (C++14)
__cpp_initializer_lists Initializer lists 200806 predefined (C++11)
__cpp_lambdas Lambda expressions 200907 predefined (C++11)
__cpp_lib_chrono_udls User-defined Literals for Time Types 201304 <chrono> (C++14)
__cpp_lib_complex_udls User-defined Literals for std::complex 201309 <complex> (C++14)
__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_generic_associative_lookup Adding heterogeneous comparison lookup to associative containers 201304 <map> <set> (C++14)
__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_is_final std::is_final 201402 <type_traits> (C++14)
__cpp_lib_is_null_pointer std::is_null_pointer 201309 <type_traits> (C++14)
__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_null_iterators Null ForwardIterators 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_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_shared_timed_mutex A proposal to 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_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)
__cpp_nsdmi Non-static data member initializers 200809 predefined (C++11)
__cpp_range_based_for Range-for loop 200907 predefined (C++11)
__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)
__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)

[edit] 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
#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
#    define DEPRECATED(msg)
DEPRECATED("foo() has been deprecated") void foo();
#if __cpp_constexpr >= 201304                   // Check for a specific version of a feature
#  define CONSTEXPR constexpr
#  define CONSTEXPR
CONSTEXPR int bar(unsigned i)
#ifdef __cpp_binary_literals                    // Check for the presence of a feature
    unsigned mask1 = 0b11000000;
    unsigned mask2 = 0b00000111;
    unsigned mask1 = 0xA0;
    unsigned mask2 = 0x07;
    if ( i & mask1 )
        return 1;
    if ( i & mask2 )
        return 2;
    return 0;
int main()

[edit] See Also

Standing Document 6 The official document on Feature Test Recommendations