Feature testing (since C++20)
The standard defines a set of preprocessor macros corresponding to C++ language and library features introduced in C++11 or later. They are intended as a simple and portable way to detect the presence of said features.
Contents |
[edit] Attributes
__has_cpp_attribute( attribute-token )
|
|||||||||
Checks for the support of an attribute named by attribute-token (after macro expansion).
For each standard attribute, it is implementation-defined whether __has_cpp_attribute
expands to the value given in the table below (which is the year and month in which the attribute was added to the working draft) or 0. It will expand to given value in the table if and only if the standard attribute causes the implementation to behave as recommended (issuing diagnostic messages, affecting class layout, etc.).
The presence of vendor-specific attributes is determined by a non-zero value.
__has_cpp_attribute
can be expanded in the expression of
#if and
#elif.
It is treated as a defined macro by
#ifdef,
#ifndef,
#elifdef,
#elifndef(since C++23) and defined but cannot be used anywhere else.
attribute-token | Attribute | Value | Std | Paper(s) |
---|---|---|---|---|
assume
|
[[assume]]
|
202207L
|
(C++23) | P1774R8 |
carries_dependency
|
[[carries_dependency]]
|
200809L
|
(C++11) (until C++26) |
N2556 N2643 P3475R2 |
deprecated
|
[[deprecated]]
|
201309L
|
(C++14) | N3760 |
fallthrough
|
[[fallthrough]]
|
201603L
|
(C++17) | P0188R1 |
indeterminate
|
[[indeterminate]]
|
202403L
|
(C++26) | P2795R5 |
likely
|
[[likely]]
|
201803L
|
(C++20) | P0479R5 |
maybe_unused
|
[[maybe_unused]]
|
201603L
|
(C++17) | P0212R1 |
no_unique_address
|
[[no_unique_address]]
|
201803L
|
(C++20) | P0840R2 |
nodiscard
|
[[nodiscard]]
|
201603L
|
(C++17) | P0189R1 |
[[nodiscard]] with reason
|
201907L
|
(C++20) | P1301R4 | |
noreturn
|
[[noreturn]]
|
200809L
|
(C++11) | N2761 |
unlikely
|
[[unlikely]]
|
201803L
|
(C++20) | P0479R5 |
Total number of attributes: 11 |
[edit] Language features
The following macros can be used to detect whether a language feature is implemented by the current implementation. They are predefined in every translation unit.
Each macro expands to an integer literal corresponding to the year and month when the corresponding feature has been included in the working draft. When a feature changes significantly, the macro will be updated accordingly.
Macro name | Feature | Value | Std | Paper(s) |
---|---|---|---|---|
__cpp_aggregate_bases
|
Aggregate classes with base classes | 201603L
|
(C++17) | P0017R1 |
__cpp_aggregate_nsdmi
|
Aggregate classes with default member initializers | 201304L
|
(C++14) | N3653 |
__cpp_aggregate_paren_init
|
Aggregate initialization in the form of direct initialization | 201902L
|
(C++20) | P0960R3 |
__cpp_alias_templates
|
Alias templates | 200704L
|
(C++11) | N2258 |
__cpp_aligned_new
|
Dynamic memory allocation for over-aligned data | 201606L
|
(C++17) | P0035R4 |
__cpp_attributes
|
Attributes | 200809L
|
(C++11) | N2761 |
__cpp_auto_cast
|
auto(x) and auto{x} | 202110L
|
(C++23) | P0849R8 |
__cpp_binary_literals
|
Binary literals | 201304L
|
(C++14) | N3472 |
__cpp_capture_star_this
|
Lambda capture of *this by value as [=,*this] | 201603L
|
(C++17) | P0018R3 |
__cpp_char8_t
|
char8_t | 201811L
|
(C++20) | P0482R6 |
char8_t compatibility and portability fix (allow initialization of (unsigned) char arrays from UTF-8 string literals) | 202207L
|
(C++23) (DR20) |
P2513R4 | |
__cpp_concepts
|
Concepts | 201907L
|
(C++20) | P0734R0 P1084R2 P1452R2 |
Conditional trivial special member functions | 202002L
|
P0848R3 P2493R0 | ||
__cpp_conditional_explicit
|
explicit(bool)
|
201806L
|
(C++20) | P0892R2 |
__cpp_consteval
|
Immediate functions | 201811L
|
(C++20) | P1073R3 |
Making consteval propagate up | 202211L
|
(C++23) (DR20) |
P2564R3 | |
__cpp_constexpr
|
constexpr | 200704L
|
(C++11) | N2235 |
Relaxed constexpr, non-const constexpr methods
|
201304L
|
(C++14) | N3652 | |
Constexpr lambda | 201603L
|
(C++17) | P0170R1 | |
Virtual function calls in constant expressions; try blocks in constexpr functions, dynamic_cast and polymorphic typeid in constant expressions; trivial default initialization and asm-declaration in constexpr functions
|
201907L
|
(C++20) | P1064R0 P1002R1 P1327R1 P1331R2 P1668R1 | |
Changing the active member of a union in constant evaluation | 202002L
|
P1330R0 P2493R0 | ||
Non-literal variables, labels, and goto statements in constexpr functions | 202110L
|
(C++23) | P2242R3 | |
Relaxing some restrictions on constexpr functions and function templates | 202207L
|
P2448R2 | ||
Permitting static constexpr variables in constexpr functions | 202211L
|
P2647R1 | ||
Constexpr cast from void*: towards constexpr type-erasure | 202306L
|
(C++26) | P2738R1 | |
constexpr placement new | 202406L
|
P2747R2 | ||
__cpp_constexpr_dynamic_alloc
|
Operations for dynamic storage duration in constexpr functions | 201907L
|
(C++20) | P0784R7 |
__cpp_constexpr_exceptions
|
constexpr exceptions: [1], [2] | 202411L
|
(C++26) | P3068R6 |
__cpp_constexpr_in_decltype
|
Generation of function and variable definitions when needed for constant evaluation | 201711L
|
(C++20) (DR11) |
P0859R0 |
__cpp_constinit
|
constinit |