Defined in header <type_traits>
template< class T >
struct is_aggregate;
(since C++17)

Checks if T is an aggregate type. The member constant value is equal to true if T is an aggregate type and false otherwise.

The behavior is undefined if T is an incomplete type other than an array type or (possibly cv-qualified) void.

The behavior of a program that adds specializations for is_aggregate or is_aggregate_v is undefined.

Template parameters

T - a type to check

Helper variable template

template< class T >
inline constexpr bool is_aggregate_v = is_aggregate<T>::value;
(since C++17)

Inherited from std::integral_constant

Member constants

true if T is an aggregate type, false otherwise
(public static member constant)

Member functions

operator bool
converts the object to bool, returns value
(public member function)
returns value
(public member function)

Member types

Type Definition
value_type bool
type std::integral_constant<bool, value>


Feature-test macro Value Std Comment
__cpp_lib_is_aggregate 201703L (C++17) std::is_agregate


#include <new>
#include <type_traits>
#include <utility>
// constructs a T at the uninitialized memory pointed to by p using
// list-initialization for aggregates and non-list initialization otherwise
template<class T, class... Args>
T* construct(T* p, Args&&... args)
    if constexpr (std::is_aggregate_v<T>)
        return ::new (static_cast<void*>(p)) T{std::forward<Args>(args)...};
        return ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
struct A { int x, y; };
struct B { B(int, const char*) {} };
int main()
    std::aligned_union_t<1, A, B> storage;
    [[maybe_unused]] A* a = construct(reinterpret_cast<A*>(&storage), 1, 2);
    [[maybe_unused]] B* b = construct(reinterpret_cast<B*>(&storage), 1, "hello");

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3823 C++17 The behavior is undefined if T is an array type but
std::remove_all_extents_t<T> is an incomplete type.
The behavior is defined regardless of the
incompleteness of std::remove_all_extents_t<T>
as long as T is an array type.

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.