◐ Shell
clean mode source ↗

Prueba de características (desde C++20)

El estándar define un conjunto de macros de preprocesador correspondiente a las características del lenguaje y las biblioteca de C++, introducidas en C++11 o posterior. Pretenden ser una forma simple y portátil de detectar la presencia de dichas características.

Verifica la presencia de un atributo denominado por token-de-atributo (después de la expansión de macro).

Para cada atributos estándar, la implementación define si __has_cpp_attribute se expandirá al valor que aparece en la tabla siguiente (que corresponde a año y mes en que el atributo se agregó al borrador de trabajo) o a 0. Se expandirá al valor mostrado en la tabla solamente si el atributo estándar provoca que la implementación se comporte según la recomendación (creando mensajes de diagnóstico, afectando a la estructura de las clases, etc.).

La presencia de atributos específicos del proveedor se determina por un valor distinto de cero.

__has_cpp_attribute se puede expandir en la expresión de #if y #elif. Se trata como una macro definida por #ifdef, #ifndef, #elifdef, #elifndef (desde C++23) y defined, pero no se puede usar en ninguna otra parte.

Las siguientes macros se pueden usar para detectar cunado una característica del lungujae está implementada en la versión actual. Están predefinidas en cada unidad de traducción.

Cada macro se expande a un literal entero correspondiente al año y mes cuando la característica correspondiente se incluyó en el borrador de trabajo. Cuando una característica cambia significativamente, la macro se actualizará en consecuencia.

Las siguientes macros se pueden usar para detectar si una característica de la biblioteca estándar está implementada en la implementación actual. A diferencia de las macros de comprobación de característica del lenguaje, no están predefinidas. Las proporciona el encabezado <version>.

Para cada macro de prueba de características de biblioteca, también las proporcionan los archivos de cabecera que proporcionan los componentes de la biblioteca estándar correspondientes. Vea macros de prueba de características de biblioteca para un listado completo de archivos de cabecera que proporcionan estas macros.

Cada macro se expande a un literal entero correspondiente al año y mes cuando la característica correspondiente se incluyó en el borrador de trabajo. Cuando una característica cambia significativamente, la macro se actualizará en consecuencia.

Nombre de la macro Característica Valor Encabezado Estándar __cpp_lib_adaptor_iterator_pair_constructor Constructores de iteradores con un std::pair para std::stack y std::queue 202106L <stack> <queue> (C++23) __cpp_lib_addressof_constexpr std::addressof constexpr 201603L <memory> (C++17) __cpp_lib_allocate_at_least std::allocate_at_least etc. 202106L <memory> (C++23) __cpp_lib_allocator_traits_is_always_equal std::allocator_traits::is_always_equal 201411L <memory> <scoped_allocator> <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++17) __cpp_lib_any std::any 201606L <any> (C++17) __cpp_lib_apply std::apply 201603L <tuple> (C++17) __cpp_lib_array_constexpr Añadir modificadores constexpr a std::reverse_iterator, std::move_iterator, std::array y acceso a rango 201603L <iterator> <array> (C++17) ConstexprIterator; comparación constexpr para std::array; constexpr misceláneos (std::array::fill et al.) 201811L <iterator> <array> (C++20) __cpp_lib_as_const std::as_const 201510L <utility> (C++17) __cpp_lib_associative_heterogeneous_erasure Borrado heterogéneo en los contenedores asociativos y los contenedores asociativos no ordenados 202110L <map> <set> <unordered_map> <unordered_set> (C++23) __cpp_lib_assume_aligned std::assume_aligned 201811L <memory> (C++20) __cpp_lib_atomic_flag_test std::atomic_flag::test 201907L <atomic> (C++20) __cpp_lib_atomic_float Atómico de punto flotante 201711L <atomic> (C++20) __cpp_lib_atomic_is_always_lock_free constexpr atomic<T>::is_always_lock_free 201603L <atomic> (C++17) __cpp_lib_atomic_lock_free_type_aliases Tipos enteros sin bloqueo atómico (std::atomic_signed_lock_free, std::atomic_unsigned_lock_free) 201907L <atomic> (C++20) __cpp_lib_atomic_ref std::atomic_ref 201806L <atomic> (C++20) __cpp_lib_atomic_shared_ptr std::atomic<std::shared_ptr> 201711L <memory> (C++20) __cpp_lib_atomic_value_initialization Reparar la inicialización atómica (inicializar por defecto a std::atomic por valor) 201911L <atomic> <memory> (C++20) __cpp_lib_atomic_wait Espera std::atomic eficiente 201907L <atomic> (C++20) __cpp_lib_barrier std::barrier 201907L <barrier> (C++20) __cpp_lib_bind_back std::bind_back 202202L <functional> (C++23) __cpp_lib_bind_front std::bind_front 201811L <functional> (C++20) __cpp_lib_bit_cast std::bit_cast 201806L <bit> (C++20) __cpp_lib_bitops Operaciones de bits 201907L <bit> (C++20) __cpp_lib_bool_constant std::bool_constant 201505L <type_traits> (C++17) __cpp_lib_bounded_array_traits std::is_bounded_array, std::is_unbounded_array 201902L <type_traits> (C++20) __cpp_lib_boyer_moore_searcher Buscadores 201603L <functional> (C++17) __cpp_lib_byte std::byte 201603L <cstddef> (C++17) __cpp_lib_byteswap std::byteswap 202110L <bit> (C++23) __cpp_lib_char8_t Apoyo de la biblioteca para char8_t 201907L <atomic> <filesystem> <istream> <limits> <locale> <ostream> <string> <string_view> (C++20) __cpp_lib_chrono Funciones de redondeo para std::chrono::duration y std::chrono::time_point 201510L <chrono> (C++17) Constexpr para todas las funciones miembro de std::chrono::duration y std::chrono::time_point 201611L <chrono> (C++17) Calendarios y Husos horarios 201907L <chrono> (C++20) __cpp_lib_chrono_udls Literales definidos por el usuario para tipos de tiempo 201304L <chrono> (C++14) __cpp_lib_clamp std::clamp 201603L <algorithm> (C++17) __cpp_lib_complex_udls Literales definidos por el usuario para std::complex 201309L <complex> (C++14) __cpp_lib_concepts Conceptos de la biblioteca estándar 201806L <concepts> (C++20) __cpp_lib_constexpr_algorithms Constexpr para algoritmos 201806L <algorithm> (C++20) __cpp_lib_constexpr_cmath Constexpr para funciones matemáticas en <cmath> y <cstdlib> 202202L <cmath> <cstdlib> (C++23) __cpp_lib_constexpr_complex Constexpr para std::complex 201711L <complex> (C++20) __cpp_lib_constexpr_dynamic_alloc Constexpr para std::allocator y utilerías relacionadas 201907L <memory> (C++20) __cpp_lib_constexpr_functional Constexpr misceláneos (std::default_searcher); constexpr INVOKE 201907L <functional> (C++20) __cpp_lib_constexpr_iterator Constexpr misceláneos (std::insert_iterator et al.) 201811L <iterator> (C++20) __cpp_lib_constexpr_memory Constexpr en std::pointer_traits 201811L <memory> (C++20) Constexpr std::unique_ptr 202202L <memory> (C++23) __cpp_lib_constexpr_numeric Constexpr para algoritmos in <numeric> 201911L <numeric> (C++20) __cpp_lib_constexpr_string Constexpr para std::string 201907L <string> (C++20) __cpp_lib_constexpr_string_view Constexpr misceláneos (std::string_view::copy) 201811L <string_view> (C++20) __cpp_lib_constexpr_tuple Constexpr misceláneos (std::tuple::operator= et al.) 201811L <tuple> (C++20) __cpp_lib_constexpr_typeinfo Constexpr misceláneos std::type_info::operator== 202106L <typeinfo> (C++23) __cpp_lib_constexpr_utility Constexpr misceláneos (std::pair::operator= et al.) 201811L <utility> (C++20) __cpp_lib_constexpr_vector Constexpr para std::vector 201907L <vector> (C++20) __cpp_lib_containers_ranges Construcción de rangos e inserción para contenedores 202202L <vector> <list> <forward_list> <map> <set> <unordered_map> <unordered_set> <deque> <queue> <stack> <string> (C++23) __cpp_lib_coroutine Corrutinas (apoyo de biblioteca) 201902L <coroutine> (C++20) __cpp_lib_destroying_delete Operador delete de destrucción (apoyo de biblioteca) 201806L <new> (C++20) __cpp_lib_enable_shared_from_this Especificación más precisa de std::enable_shared_from_this 201603L <memory> (C++17) __cpp_lib_endian std::endian 201907L <bit> (C++20) __cpp_lib_erase_if Borrado uniforme de contenedores 201811L <string> <deque> <forward_list> <list> <vector> <map> <set> <unordered_map> <unordered_set> (C++20) __cpp_lib_exchange_function std::exchange 201304L <utility> (C++14) __cpp_lib_execution Políticas de ejecución 201603L <execution> (C++17) std::execution::unsequenced_policy 201902L <execution> (C++20) __cpp_lib_expected Plantilla de clase std::expected 202202L <expected> (C++23) __cpp_lib_filesystem Biblioteca del sistema de archivos 201703L <filesystem> (C++17) __cpp_lib_format Formateo de texto 201907L <format> (C++20) Verificaciones de cadena de formato en tiempo de compilación, reducir la parametrización de std::vformat_to 202106L <format> (C++20)(DR) Reparar el manejo de la configuración regional en los formateadores de chrono; apoyar los tipos no const formateables 202110L <format> (C++20)(DR) __cpp_lib_gcd_lcm std::gcd, std::lcm 201606L <numeric> (C++17) __cpp_lib_generic_associative_lookup Búsqueda de comparación heterogénea en los contenedores asociativos 201304L <map> <set> (C++14) __cpp_lib_generic_unordered_lookup Búsqueda de comparación heterogénea en los contenedores asociativos no ordenados 201811L <unordered_map> <unordered_set> (C++20) __cpp_lib_hardware_interference_size constexpr std::hardware_{constructive, destructive}_interference_size 201703L <new> (C++17) __cpp_lib_has_unique_object_representations std::has_unique_object_representations 201606L <type_traits> (C++17) __cpp_lib_hypot Sobrecarga de 3 argumentos de std::hypot 201603L <cmath> (C++17) __cpp_lib_incomplete_container_elements Apoyo mínimo de tipos incompletos para los contenedores estándar para std::forward_list, std::list, y std::vector 201505L <forward_list> <list> <vector> (C++17) __cpp_lib_int_pow2 Operaciones enteras de potencias al cuadrado (std::has_single_bit, std::bit_ceil, std::bit_floor, std::bit_width) 202002L <bit> (C++20) __cpp_lib_integer_comparison_functions Funciones de comparación de enteros 202002L <utility> (C++20) __cpp_lib_integer_sequence Secuencias de enteros en tiempo de compilación 201304L <utility> (C++14) __cpp_lib_integral_constant_callable std::integral_constant 201304L <type_traits> (C++14) __cpp_lib_interpolate std::lerp(), std::midpoint() 201902L <cmath> <numeric> (C++20) __cpp_lib_invoke Plantilla de función std::invoke 201411L <functional> (C++17) __cpp_lib_invoke_r std::invoke_r 202106L <functional> (C++23) __cpp_lib_is_aggregate Rasgo de tipo std::is_aggregate 201703L <type_traits> (C++17) __cpp_lib_is_constant_evaluated std::is_constant_evaluated 201811L <type_traits> (C++20) __cpp_lib_is_final std::is_final 201402L <type_traits> (C++14) __cpp_lib_is_invocable std::is_invocable, std::invoke_result 201703L <type_traits> (C++17) __cpp_lib_is_layout_compatible std::is_layout_compatible 201907L <type_traits> (C++20) __cpp_lib_is_nothrow_convertible std::is_nothrow_convertible 201806L <type_traits> (C++20) __cpp_lib_is_null_pointer std::is_null_pointer 201309L <type_traits> (C++14) __cpp_lib_is_pointer_interconvertible Rasgos de interconvertibilidad de punteros: std::is_pointer_interconvertible_with_class, std::is_pointer_interconvertible_base_of 201907L <type_traits> (C++20) __cpp_lib_is_scoped_enum std::is_scoped_enum 202011L <type_traits> (C++23) __cpp_lib_is_swappable Rasgos de intercambio [nothrow-] 201603L <type_traits> (C++17) __cpp_lib_jthread Token de detención e hilo de unión 201911L <stop_token> <thread> (C++20) __cpp_lib_latch std::latch 201907L <latch> (C++20) __cpp_lib_launder Asunto principal 1776: Reemplazo de objetos clase que contienen miembros de tipo referencia (std::launder) 201606L <new> (C++17) __cpp_lib_list_remove_return_type Cambiar el tipo de retorno de los miembros std::list::remove, std::list::remove_if y std::list::unique de std::forward_list y std::list 201806L <forward_list> <list> (C++20) __cpp_lib_logical_traits Rasgos de tipo de operadores lógicos 201510L <type_traits> (C++17) __cpp_lib_make_from_tuple std::make_from_tuple 201606L <tuple> (C++17) __cpp_lib_make_reverse_iterator std::make_reverse_iterator 201402L <iterator> (C++14) __cpp_lib_make_unique std::make_unique 201304L <memory> (C++14) __cpp_lib_map_try_emplace std::map::try_emplace, std::map::insert_or_assign 201411L <map> (C++17) __cpp_lib_math_constants Constantes matemáticas 201907L <numbers> (C++20) __cpp_lib_math_special_functions Funciones matemáticas especiales para C++17 201603L <cmath> (C++17) __cpp_lib_memory_resource std::pmr::memory_resource 201603L <memory_resource> (C++17) __cpp_lib_move_only_function std::move_only_function 202110L <functional> (C++23) __cpp_lib_node_extract Unir mapas y conjuntos (std::map::extract, std::map::merge, std::map::insert(node_type), etc) 201606L <map> <set> <unordered_map> <unordered_set> (C++17) __cpp_lib_nonmember_container_access std::size(), std::data() y std::empty() 201411L <iterator> <array> <deque> <forward_list> <list> <map> <regex> <set> <string> <unordered_map> <unordered_set> <vector> (C++17) __cpp_lib_not_fn std::not_fn 201603L <functional> (C++17) __cpp_lib_null_iterators Iteradores de avance nulos 201304L <iterator> (C++14) __cpp_lib_optional std::optional 201606L <optional> (C++17) std::optional completamente constexpr 202106L <optional> (C++20)(DR) Operaciones monádicas en std::optional 202110L <optional> (C++23) __cpp_lib_out_ptr std::out_ptr, std::inout_ptr 202106L <memory> (C++23) __cpp_lib_parallel_algorithm Algoritmos paralelos 201603L <algorithm> <numeric> (C++17) __cpp_lib_polymorphic_allocator std::pmr::polymorphic_allocator como un tipo vocabulario 201902L <memory_resource> (C++20) __cpp_lib_quoted_string_io std::quoted 201304L <iomanip> (C++14) __cpp_lib_ranges Biblioteca de rangos y algoritmos restringidos 201911L <algorithm> <functional> <iterator> <memory> <ranges> (C++20) Vistas no inicializables por defecto 202106L (C++20)(DR) Vistas con propiedad 202110L (C++20)(DR) std::ranges::range_adaptor_closure 202202L (C++23) __cpp_lib_ranges_chunk std::ranges::chunk_view 202202L <ranges> (C++23) __cpp_lib_ranges_chunk_by std::ranges::chunk_by_view 202202L <ranges> (C++23) __cpp_lib_ranges_iota std::ranges::iota 202202L <numeric> (C++23) __cpp_lib_ranges_join_with std::ranges::join_with_view 202202L <ranges> (C++23) __cpp_lib_ranges_slide std::ranges::slide_view 202202L <ranges> (C++23) __cpp_lib_ranges_starts_ends_with std::ranges::starts_with, std::ranges::ends_with 202106L <algorithm> (C++23) __cpp_lib_ranges_to_container std::ranges::to 202202L <ranges> (C++23) __cpp_lib_ranges_zip std::ranges::zip_view, std::ranges::zip_transform_view, std::ranges::adjacent_view, std::ranges::adjacent_transform_view 202110L <ranges> <tuple> <utility> (C++23) __cpp_lib_raw_memory_algorithms Extender herramientas de gestión de memoria 201606L <memory> (C++17) __cpp_lib_reference_from_temporary std::reference_constructs_from_temporary y std::reference_converts_from_temporary 202202L <type_traits> (C++23) __cpp_lib_remove_cvref std::remove_cvref 201711L <type_traits> (C++20) __cpp_lib_result_of_sfinae std::result_of y SFINAE 201210L <functional> <type_traits> (C++14) __cpp_lib_robust_nonmodifying_seq_ops Hacer operaciones de secuencias no modificadoras más robustas (sobrecargas de dos rangos para std::mismatch, std::equal y std::is_permutation) 201304L <algorithm> (C++14) __cpp_lib_sample std::sample 201603L <algorithm> (C++17) __cpp_lib_scoped_lock std::lock_guard variádico (std::scoped_lock) 201703L <mutex> (C++17) __cpp_lib_semaphore std::counting_semaphore, std::binary_semaphore 201907L <semaphore> (C++20) __cpp_lib_shared_mutex std::shared_mutex (no temporizado) 201505L <shared_mutex> (C++17) __cpp_lib_shared_ptr_arrays std::shared_ptr 201611L <memory> (C++17) Apoyo de arrays para std::make_shared 201707L <memory> (C++20) __cpp_lib_shared_ptr_weak_type shared_ptr::weak_type 201606L <memory> (C++17) __cpp_lib_shared_timed_mutex std::shared_timed_mutex 201402L <shared_mutex> (C++14) __cpp_lib_shift std::shift_left y std::shift_right 201806L <algorithm> (C++20) std::ranges::shift_left y std::ranges::shift_right 202202L <algorithm> (C++23) __cpp_lib_smart_ptr_for_overwrite Creación de puntero inteligente con inicialización por defecto (std::allocate_shared_for_overwrite, std::make_shared_for_overwrite, std::make_unique_for_overwrite) 202002L <memory> (C++20) __cpp_lib_source_location Captura de información de código fuente (std::source_location) 201907L <source_location> (C++20) __cpp_lib_span std::span 202002L <span> (C++20) __cpp_lib_spanstream std::spanbuf, std::spanstream 202106L <spanstream> (C++23) __cpp_lib_ssize std::ssize y std::span::size sin signo 201902L <iterator> (C++20) __cpp_lib_stacktrace Listado de pila 202011L <stacktrace> (C++23) __cpp_lib_starts_ends_with Verificación de prefijo y sufijo de cadenas (std::string_view::starts_with y std::string_view::ends_with para std::string y std::string_view) 201711L <string> <string_view> (C++20) __cpp_lib_stdatomic_h Encabezado de compatibilidad para operaciones atómicas en C 202011L <stdatomic.h> (C++23) __cpp_lib_string_contains Funciones contains de std::basic_string y std::basic_string_view 202011L <string> <string_view> (C++23) __cpp_lib_string_resize_and_overwrite std::basic_string::resize_and_overwrite 202110L <string> (C++23) __cpp_lib_string_udls Literales definidos por el usuario para tipos cadena 201304L <string> (C++14) __cpp_lib_string_view std::string_view 201606L <string> <string_view> (C++17) ConstexprIterator 201803L <string> <string_view> (C++20) __cpp_lib_syncbuf Flujo de salida con búfer sincronizado (std::syncbuf, std::osyncstream) y manipuladores 201803L <syncstream> (C++20) __cpp_lib_three_way_comparison Comparación de tres vías (apoyo de biblioteca); agregar comparación de tres vías a la biblioteca 201907L <compare> (C++20) __cpp_lib_to_address Utilería para convertir un puntero a un puntero sin formato (std::to_address) 201711L <memory> (C++20) __cpp_lib_to_array std::to_array 201907L <array> (C++20) __cpp_lib_to_chars Conversiones de cadena elementales (std::to_chars, std::from_chars) 201611L <charconv> (C++17) __cpp_lib_to_underlying std::to_underlying 202102L <utility> (C++23) __cpp_lib_transformation_trait_aliases Plantillas de alias para TransformationTraits 201304L <type_traits> (C++14) __cpp_lib_transparent_operators Objetos función de operador transparentes (std::less<> et al) 201210L <functional> (C++14) std::owner_less transparente (std::owner_less<void>) 201510L <memory> <functional> (C++17) __cpp_lib_tuple_element_t std::tuple_element_t 201402L <tuple> (C++14) __cpp_lib_tuples_by_type Dirigirse a las tuplas por tipo 201304L <tuple> <utility> (C++14) __cpp_lib_type_identity std::type_identity 201806L <type_traits> (C++20) __cpp_lib_type_trait_variable_templates Plantillas de variable de rasgos de tipo (std::is_void_v, etc.) 201510L <type_traits> (C++17) __cpp_lib_uncaught_exceptions std::uncaught_exceptions 201411L <exception> (C++17) __cpp_lib_unordered_map_try_emplace std::unordered_map::try_emplace, std::unordered_map::insert_or_assign 201411L <unordered_map> (C++17) __cpp_lib_unreachable std::unreachable 202202L <utility> (C++23) __cpp_lib_unwrap_ref std::unwrap_ref_decay y std::unwrap_reference 201811L <type_traits> (C++20) __cpp_lib_variant std::variant: una unión de tipo seguro para C++17 201606L <variant> (C++17) std::visit para clases derivadas de std::variant 202102L <variant> (C++17)(DR) std::variant complatamente constexpr 202106L <variant> (C++20)(DR) __cpp_lib_void_t std::void_t 201411L <type_traits> (C++17)

El siguiente programa vuelca las características y atributos de C++ del compilador.

// Cambia estas opciones para imprimir solo la información necesaria.
static struct PrintOptions {
    constexpr static bool titles               = 1;
    constexpr static bool counters             = 1;
    constexpr static bool attributes           = 1;
    constexpr static bool general_features     = 1;
    constexpr static bool core_features        = 1;
    constexpr static bool lib_features         = 1;
    constexpr static bool supported_features   = 1;
    constexpr static bool unsupported_features = 1;
    constexpr static bool sorted_by_value      = 0;
    constexpr static bool cxx11                = 1;
    constexpr static bool cxx14                = 1;
    constexpr static bool cxx17                = 1;
    constexpr static bool cxx20                = 1;
    constexpr static bool cxx23                = 1;
}   print;

#if __cplusplus < 201100
#  error "Se requiere C++11 o posterior"
#endif

#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>

#ifdef __has_include
# if __has_include(<version>)
#   include <version>
# endif
#endif

#define COMPILER_FEATURE_VALUE(value) #value
#define COMPILER_FEATURE_ENTRY(name) { #name, COMPILER_FEATURE_VALUE(name) },

#ifdef __has_cpp_attribute
# define COMPILER_ATTRIBUTE_VALUE_AS_STRING(s) #s
# define COMPILER_ATTRIBUTE_AS_NUMBER(x) COMPILER_ATTRIBUTE_VALUE_AS_STRING(x)
# define COMPILER_ATTRIBUTE_ENTRY(attr) \
  { #attr, COMPILER_ATTRIBUTE_AS_NUMBER(__has_cpp_attribute(attr)) },
#else
# define COMPILER_ATTRIBUTE_ENTRY(attr) { #attr, "_" },
#endif

struct CompilerFeature {
    CompilerFeature(const char* name = nullptr, const char* value = nullptr)
        : name(name), value(value) {}
    const char* name; const char* value;
};

static CompilerFeature cxx_core[] = {
COMPILER_FEATURE_ENTRY(__cplusplus)
COMPILER_FEATURE_ENTRY(__cpp_exceptions)
COMPILER_FEATURE_ENTRY(__cpp_rtti)
#if 0
COMPILER_FEATURE_ENTRY(__GNUC__)
COMPILER_FEATURE_ENTRY(__GNUC_MINOR__)
COMPILER_FEATURE_ENTRY(__GNUC_PATCHLEVEL__)
COMPILER_FEATURE_ENTRY(__GNUG__)
COMPILER_FEATURE_ENTRY(__clang__)
COMPILER_FEATURE_ENTRY(__clang_major__)
COMPILER_FEATURE_ENTRY(__clang_minor__)
COMPILER_FEATURE_ENTRY(__clang_patchlevel__)
#endif
};
static CompilerFeature cxx11_core[] = {
COMPILER_FEATURE_ENTRY(__cpp_alias_templates)
COMPILER_FEATURE_ENTRY(__cpp_attributes)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_decltype)
COMPILER_FEATURE_ENTRY(__cpp_delegating_constructors)
COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(__cpp_initializer_lists)
COMPILER_FEATURE_ENTRY(__cpp_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_nsdmi)
COMPILER_FEATURE_ENTRY(__cpp_range_based_for)
COMPILER_FEATURE_ENTRY(__cpp_raw_strings)
COMPILER_FEATURE_ENTRY(__cpp_ref_qualifiers)
COMPILER_FEATURE_ENTRY(__cpp_rvalue_references)
COMPILER_FEATURE_ENTRY(__cpp_static_assert)
COMPILER_FEATURE_ENTRY(__cpp_threadsafe_static_init)
COMPILER_FEATURE_ENTRY(__cpp_unicode_characters)
COMPILER_FEATURE_ENTRY(__cpp_unicode_literals)
COMPILER_FEATURE_ENTRY(__cpp_user_defined_literals)
COMPILER_FEATURE_ENTRY(__cpp_variadic_templates)
};
static CompilerFeature cxx14_core[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_nsdmi)
COMPILER_FEATURE_ENTRY(__cpp_binary_literals)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_decltype_auto)
COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_init_captures)
COMPILER_FEATURE_ENTRY(__cpp_return_type_deduction)
COMPILER_FEATURE_ENTRY(__cpp_sized_deallocation)
COMPILER_FEATURE_ENTRY(__cpp_variable_templates)
};
static CompilerFeature cxx14_lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_complex_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_exchange_function)
COMPILER_FEATURE_ENTRY(__cpp_lib_generic_associative_lookup)
COMPILER_FEATURE_ENTRY(__cpp_lib_integer_sequence)
COMPILER_FEATURE_ENTRY(__cpp_lib_integral_constant_callable)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_final)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_null_pointer)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_reverse_iterator)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_unique)
COMPILER_FEATURE_ENTRY(__cpp_lib_null_iterators)
COMPILER_FEATURE_ENTRY(__cpp_lib_quoted_string_io)
COMPILER_FEATURE_ENTRY(__cpp_lib_result_of_sfinae)
COMPILER_FEATURE_ENTRY(__cpp_lib_robust_nonmodifying_seq_ops)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_timed_mutex)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_udls)
COMPILER_FEATURE_ENTRY(__cpp_lib_transformation_trait_aliases)
COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(__cpp_lib_tuple_element_t)
COMPILER_FEATURE_ENTRY(__cpp_lib_tuples_by_type)
};

static CompilerFeature cxx17_core[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_bases)
COMPILER_FEATURE_ENTRY(__cpp_aligned_new)
COMPILER_FEATURE_ENTRY(__cpp_capture_star_this)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(__cpp_enumerator_attributes)
COMPILER_FEATURE_ENTRY(__cpp_fold_expressions)
COMPILER_FEATURE_ENTRY(__cpp_guaranteed_copy_elision)
COMPILER_FEATURE_ENTRY(__cpp_hex_float)
COMPILER_FEATURE_ENTRY(__cpp_if_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_inheriting_constructors)
COMPILER_FEATURE_ENTRY(__cpp_inline_variables)
COMPILER_FEATURE_ENTRY(__cpp_namespace_attributes)
COMPILER_FEATURE_ENTRY(__cpp_noexcept_function_type)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_parameter_auto)
COMPILER_FEATURE_ENTRY(__cpp_range_based_for)
COMPILER_FEATURE_ENTRY(__cpp_static_assert)
COMPILER_FEATURE_ENTRY(__cpp_structured_bindings)
COMPILER_FEATURE_ENTRY(__cpp_template_template_args)
COMPILER_FEATURE_ENTRY(__cpp_variadic_using)
};
static CompilerFeature cxx17_lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_addressof_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_allocator_traits_is_always_equal)
COMPILER_FEATURE_ENTRY(__cpp_lib_any)
COMPILER_FEATURE_ENTRY(__cpp_lib_apply)
COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_as_const)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_is_always_lock_free)
COMPILER_FEATURE_ENTRY(__cpp_lib_bool_constant)
COMPILER_FEATURE_ENTRY(__cpp_lib_boyer_moore_searcher)
COMPILER_FEATURE_ENTRY(__cpp_lib_byte)
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(__cpp_lib_clamp)
COMPILER_FEATURE_ENTRY(__cpp_lib_enable_shared_from_this)
COMPILER_FEATURE_ENTRY(__cpp_lib_execution)
COMPILER_FEATURE_ENTRY(__cpp_lib_filesystem)
COMPILER_FEATURE_ENTRY(__cpp_lib_gcd_lcm)
COMPILER_FEATURE_ENTRY(__cpp_lib_hardware_interference_size)
COMPILER_FEATURE_ENTRY(__cpp_lib_has_unique_object_representations)
COMPILER_FEATURE_ENTRY(__cpp_lib_hypot)
COMPILER_FEATURE_ENTRY(__cpp_lib_incomplete_container_elements)
COMPILER_FEATURE_ENTRY(__cpp_lib_invoke)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_aggregate)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_invocable)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_swappable)
COMPILER_FEATURE_ENTRY(__cpp_lib_launder)
COMPILER_FEATURE_ENTRY(__cpp_lib_logical_traits)
COMPILER_FEATURE_ENTRY(__cpp_lib_make_from_tuple)
COMPILER_FEATURE_ENTRY(__cpp_lib_map_try_emplace)
COMPILER_FEATURE_ENTRY(__cpp_lib_math_special_functions)
COMPILER_FEATURE_ENTRY(__cpp_lib_memory_resource)
COMPILER_FEATURE_ENTRY(__cpp_lib_node_extract)
COMPILER_FEATURE_ENTRY(__cpp_lib_nonmember_container_access)
COMPILER_FEATURE_ENTRY(__cpp_lib_not_fn)
COMPILER_FEATURE_ENTRY(__cpp_lib_optional)
COMPILER_FEATURE_ENTRY(__cpp_lib_parallel_algorithm)
COMPILER_FEATURE_ENTRY(__cpp_lib_raw_memory_algorithms)
COMPILER_FEATURE_ENTRY(__cpp_lib_sample)
COMPILER_FEATURE_ENTRY(__cpp_lib_scoped_lock)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_mutex)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_weak_type)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_chars)
COMPILER_FEATURE_ENTRY(__cpp_lib_transparent_operators)
COMPILER_FEATURE_ENTRY(__cpp_lib_type_trait_variable_templates)
COMPILER_FEATURE_ENTRY(__cpp_lib_uncaught_exceptions)
COMPILER_FEATURE_ENTRY(__cpp_lib_unordered_map_try_emplace)
COMPILER_FEATURE_ENTRY(__cpp_lib_variant)
COMPILER_FEATURE_ENTRY(__cpp_lib_void_t)
};

static CompilerFeature cxx20_core[] = {
COMPILER_FEATURE_ENTRY(__cpp_aggregate_paren_init)
COMPILER_FEATURE_ENTRY(__cpp_char8_t)
COMPILER_FEATURE_ENTRY(__cpp_concepts)
COMPILER_FEATURE_ENTRY(__cpp_conditional_explicit)
COMPILER_FEATURE_ENTRY(__cpp_consteval)
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(__cpp_constexpr_in_decltype)
COMPILER_FEATURE_ENTRY(__cpp_constinit)
COMPILER_FEATURE_ENTRY(__cpp_deduction_guides)
COMPILER_FEATURE_ENTRY(__cpp_designated_initializers)
COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas)
COMPILER_FEATURE_ENTRY(__cpp_impl_coroutine)
COMPILER_FEATURE_ENTRY(__cpp_impl_destroying_delete)
COMPILER_FEATURE_ENTRY(__cpp_impl_three_way_comparison)
COMPILER_FEATURE_ENTRY(__cpp_init_captures)
COMPILER_FEATURE_ENTRY(__cpp_modules)
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args)
COMPILER_FEATURE_ENTRY(__cpp_using_enum)
};
static CompilerFeature cxx20_lib[] = {
COMPILER_FEATURE_ENTRY(__cpp_lib_array_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_lib_assume_aligned)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_flag_test)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_float)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_lock_free_type_aliases)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_ref)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_shared_ptr)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_value_initialization)
COMPILER_FEATURE_ENTRY(__cpp_lib_atomic_wait)
COMPILER_FEATURE_ENTRY(__cpp_lib_barrier)
COMPILER_FEATURE_ENTRY(__cpp_lib_bind_front)
COMPILER_FEATURE_ENTRY(__cpp_lib_bit_cast)
COMPILER_FEATURE_ENTRY(__cpp_lib_bitops)
COMPILER_FEATURE_ENTRY(__cpp_lib_bounded_array_traits)
COMPILER_FEATURE_ENTRY(__cpp_lib_char8_t)
COMPILER_FEATURE_ENTRY(__cpp_lib_chrono)
COMPILER_FEATURE_ENTRY(__cpp_lib_concepts)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_algorithms)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_complex)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_dynamic_alloc)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_functional)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_iterator)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_memory)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_numeric)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_tuple)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_utility)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_vector)
COMPILER_FEATURE_ENTRY(__cpp_lib_coroutine)
COMPILER_FEATURE_ENTRY(__cpp_lib_destroying_delete)
COMPILER_FEATURE_ENTRY(__cpp_lib_endian)
COMPILER_FEATURE_ENTRY(__cpp_lib_erase_if)
COMPILER_FEATURE_ENTRY(__cpp_lib_execution)
COMPILER_FEATURE_ENTRY(__cpp_lib_format)
COMPILER_FEATURE_ENTRY(__cpp_lib_generic_unordered_lookup)
COMPILER_FEATURE_ENTRY(__cpp_lib_int_pow2)
COMPILER_FEATURE_ENTRY(__cpp_lib_integer_comparison_functions)
COMPILER_FEATURE_ENTRY(__cpp_lib_interpolate)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_constant_evaluated)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_layout_compatible)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_nothrow_convertible)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_pointer_interconvertible)
COMPILER_FEATURE_ENTRY(__cpp_lib_jthread)
COMPILER_FEATURE_ENTRY(__cpp_lib_latch)
COMPILER_FEATURE_ENTRY(__cpp_lib_list_remove_return_type)
COMPILER_FEATURE_ENTRY(__cpp_lib_math_constants)
COMPILER_FEATURE_ENTRY(__cpp_lib_polymorphic_allocator)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(__cpp_lib_remove_cvref)
COMPILER_FEATURE_ENTRY(__cpp_lib_semaphore)
COMPILER_FEATURE_ENTRY(__cpp_lib_shared_ptr_arrays)
COMPILER_FEATURE_ENTRY(__cpp_lib_shift)
COMPILER_FEATURE_ENTRY(__cpp_lib_smart_ptr_for_overwrite)
COMPILER_FEATURE_ENTRY(__cpp_lib_source_location)
COMPILER_FEATURE_ENTRY(__cpp_lib_span)
COMPILER_FEATURE_ENTRY(__cpp_lib_ssize)
COMPILER_FEATURE_ENTRY(__cpp_lib_starts_ends_with)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_view)
COMPILER_FEATURE_ENTRY(__cpp_lib_syncbuf)
COMPILER_FEATURE_ENTRY(__cpp_lib_three_way_comparison)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_address)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_array)
COMPILER_FEATURE_ENTRY(__cpp_lib_type_identity)
COMPILER_FEATURE_ENTRY(__cpp_lib_unwrap_ref)
};

static CompilerFeature cxx23_core[] = {
//< Continuar poblando
COMPILER_FEATURE_ENTRY(__cpp_constexpr)
COMPILER_FEATURE_ENTRY(__cpp_explicit_this_parameter)
COMPILER_FEATURE_ENTRY(__cpp_if_consteval)
COMPILER_FEATURE_ENTRY(__cpp_multidimensional_subscript)
COMPILER_FEATURE_ENTRY(__cpp_size_t_suffix)
};
static CompilerFeature cxx23_lib[] = {
//< Continuar poblando
COMPILER_FEATURE_ENTRY(__cpp_lib_adaptor_iterator_pair_constructor)
COMPILER_FEATURE_ENTRY(__cpp_lib_allocate_at_least)
COMPILER_FEATURE_ENTRY(__cpp_lib_associative_heterogeneous_erasure)
COMPILER_FEATURE_ENTRY(__cpp_lib_bind_back)
COMPILER_FEATURE_ENTRY(__cpp_lib_byteswap)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_cmath)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_memory)
COMPILER_FEATURE_ENTRY(__cpp_lib_constexpr_typeinfo)
COMPILER_FEATURE_ENTRY(__cpp_lib_containers_ranges)
COMPILER_FEATURE_ENTRY(__cpp_lib_expected)
COMPILER_FEATURE_ENTRY(__cpp_lib_format)
COMPILER_FEATURE_ENTRY(__cpp_lib_invoke_r)
COMPILER_FEATURE_ENTRY(__cpp_lib_is_scoped_enum)
COMPILER_FEATURE_ENTRY(__cpp_lib_move_only_function)
COMPILER_FEATURE_ENTRY(__cpp_lib_optional)
COMPILER_FEATURE_ENTRY(__cpp_lib_out_ptr)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_chunk)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_chunk_by)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_iota)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_join_with)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_slide)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_starts_ends_with)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_to_container)
COMPILER_FEATURE_ENTRY(__cpp_lib_ranges_zip)
COMPILER_FEATURE_ENTRY(__cpp_lib_reference_from_temporary)
COMPILER_FEATURE_ENTRY(__cpp_lib_shift)
COMPILER_FEATURE_ENTRY(__cpp_lib_spanstream)
COMPILER_FEATURE_ENTRY(__cpp_lib_stacktrace)
COMPILER_FEATURE_ENTRY(__cpp_lib_stdatomic_h)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_contains)
COMPILER_FEATURE_ENTRY(__cpp_lib_string_resize_and_overwrite)
COMPILER_FEATURE_ENTRY(__cpp_lib_to_underlying)
COMPILER_FEATURE_ENTRY(__cpp_lib_unreachable)
COMPILER_FEATURE_ENTRY(__cpp_lib_variant)
};

static CompilerFeature attributes[] = {
COMPILER_ATTRIBUTE_ENTRY(carries_dependency)
COMPILER_ATTRIBUTE_ENTRY(deprecated)
COMPILER_ATTRIBUTE_ENTRY(fallthrough)
COMPILER_ATTRIBUTE_ENTRY(likely)
COMPILER_ATTRIBUTE_ENTRY(maybe_unused)
COMPILER_ATTRIBUTE_ENTRY(nodiscard)
COMPILER_ATTRIBUTE_ENTRY(noreturn)
COMPILER_ATTRIBUTE_ENTRY(no_unique_address)
COMPILER_ATTRIBUTE_ENTRY(unlikely)
};

constexpr bool is_feature_supported(const CompilerFeature& x) {
    return x.value[0] != '_' && x.value[0] != '0';
}

inline void print_compiler_feature(const CompilerFeature& x) {
    constexpr static int max_name_length = 44; //< Update if necessary
    std::string value{ is_feature_supported(x) ? x.value : "------" };
    if (value.back() == 'L') value.pop_back(); //~ 201603L -> 201603
    // value.insert(4, 1, '-'); //~ 201603 -> 2016-03
    if ( (print.supported_features && is_feature_supported(x))
        or (print.unsupported_features && !is_feature_supported(x))) {
            std::cout << std::left << std::setw(max_name_length)
                      << x.name << " " << value << '\n';
    }
}

template<size_t N>
inline void show(char const* title, CompilerFeature (&features)[N]) {
    if (print.titles) {
        std::cout << '\n' << std::left << title << " (";
        if (print.counters)
            std::cout << std::count_if(
                std::begin(features), std::end(features), is_feature_supported) << '/';
        std::cout << N << ")\n";
    }
    if (print.sorted_by_value) {
        std::sort(std::begin(features), std::end(features),
            [](CompilerFeature const& lhs, CompilerFeature const& rhs) {
                return std::strcmp(lhs.value, rhs.value) < 0;
            });
    }
    for (const CompilerFeature& x : features) {
        print_compiler_feature(x);
    }
}

int main() {
    if (print.general_features) show("C++ GENERAL", cxx_core);
    if (print.cxx11 && print.core_features) show("C++11 CORE", cxx11_core);
    if (print.cxx14 && print.core_features) show("C++14 CORE", cxx14_core);
    if (print.cxx14 && print.lib_features ) show("C++14 LIB" , cxx14_lib);
    if (print.cxx17 && print.core_features) show("C++17 CORE", cxx17_core);
    if (print.cxx17 && print.lib_features ) show("C++17 LIB" , cxx17_lib);
    if (print.cxx20 && print.core_features) show("C++20 CORE", cxx20_core);
    if (print.cxx20 && print.lib_features ) show("C++20 LIB" , cxx20_lib);
    if (print.cxx23 && print.core_features) show("C++23 CORE", cxx23_core);
    if (print.cxx23 && print.lib_features ) show("C++23 LIB" , cxx23_lib);
    if (print.attributes) show("ATTRIBUTES", attributes);
}

Posible salida:

C++ GENERAL (3/3)
__cplusplus                                  202002
__cpp_exceptions                             199711
__cpp_rtti                                   199711

C++11 CORE (19/19)
__cpp_alias_templates                        200704
__cpp_attributes                             200809
__cpp_constexpr                              201907
__cpp_decltype                               200707
__cpp_delegating_constructors                200604
__cpp_inheriting_constructors                201511
__cpp_initializer_lists                      200806
__cpp_lambdas                                200907
__cpp_nsdmi                                  200809
__cpp_range_based_for                        201603
__cpp_raw_strings                            200710
__cpp_ref_qualifiers                         200710
__cpp_rvalue_references                      200610
__cpp_static_assert                          201411
__cpp_threadsafe_static_init                 200806
__cpp_unicode_characters                     200704
__cpp_unicode_literals                       200710
__cpp_user_defined_literals                  200809
__cpp_variadic_templates                     200704

C++14 CORE (9/9)
__cpp_aggregate_nsdmi                        201304
__cpp_binary_literals                        201304
__cpp_constexpr                              201907
__cpp_decltype_auto                          201304
__cpp_generic_lambdas                        201707
__cpp_init_captures                          201803
__cpp_return_type_deduction                  201304
__cpp_sized_deallocation                     ------
__cpp_variable_templates                     201304

... truncado ...

Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.