TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #1142 3.15K
​​Базовые трейты объектов
#новичкам

Трейты(или свойства объектов) - мощнейший инструмент проверки требований для исполнения кода. Вы явно в апи через sfinae или концепты можете задавать ограничения на множество типов, с которыми хотите работать, производя проверку в compile-time.

Сегодня обсудим для самой простой структуры, какими свойствами классов она удовлетворяет. Чисто, чтобы вкатиться в базовые стандартные трейты.

Проверить свойства типа можно довольно просто. static_assert + использование самого трейта:

struct A {
int a;
int b;
int c;
};

// --- true ---
static_assert(std::is_class_v<A>, "A is a class");
static_assert(std::is_aggregate_v<A>, "A is aggregate");
static_assert(std::is_standard_layout_v<A>, "A is standard-layout");

static_assert(std::is_trivially_copyable_v<A>, "A is trivially copyable");
static_assert(std::is_trivially_destructible_v<A>, "A trivially destructible");
static_assert(std::is_trivially_copy_constructible_v<A>, "A trivial copy ctor");
static_assert(std::is_trivially_move_constructible_v<A>, "A trivial move ctor");
static_assert(std::is_trivially_copy_assignable_v<A>, "A trivial copy assign");
static_assert(std::is_trivially_move_assignable_v<A>, "A trivial move assign");

static_assert(std::is_default_constructible_v<A>, "A default constructible");
static_assert(std::is_trivially_default_constructible_v<A>, "A trivial default ctor");

static_assert(std::is_object_v<A>, "A is object");
static_assert(std::is_compound_v<A>, "A is compound");

// --- false ---
static_assert(!std::is_empty_v<A>, "A is NOT empty (has members)");
static_assert(!std::is_polymorphic_v<A>, "A is NOT polymorphic");
static_assert(!std::is_fundamental_v<A>, "A is NOT fundamental");
static_assert(!std::is_scalar_v<A>, "A is NOT scalar");


Вообще эти трейты - это некая шаблонные структуры. У них есть статический constexpr член value, который обращается в true, если свойство присутствует у типа, и в false если нет.

Для каждого трейта определен вспомогательный шаблон переменной с суффиктом _v, который хранит непосредственно булево значение.

Ну и по порядку:

✅ is_class. A действительно является полноценным классом с точки зрения С++. Структуры и классы в этом смысле не отличаются.

✅ is_aggregate. С агрегатами можно использовать инициализацию членов через список инициализации внутри {}.

✅ is_standard_layout. Очень упрощая, ваш класс не имеет виртуальных функций, все поля также являются standard_layout с одинаковым модификатором доступа и у него нет базовых классов.

✅ is_trivially_copyable. Класс имеет хотя бы один копирующий или перемещающий специальный метод и все они сгенерированы компилятором.

✅ is_trivially_destructible, is_trivially_copy_constructible,is_trivially_move_constructible, is_trivially_copy_assignable, is_trivially_move_assignable_v - соответствующий специальный метод должен быть сгенерирован компилятором.

Есть также версия без trivially, которая просто проверяет наличие операции в классе.

✅ is_trivially_default_constructible - дефолтный конструктор сгенерен компилятором и внутри него не выполняется никакой код(все поля типа должны иметь тривиальный дефолтный контруктор, то есть состоять только из тривиальных типов).

✅ is_object -  Все, что не ссылка, не функция и не void, то объект. Интересно, что A - это и класс, и объект. Вот такое ООП в плюсах, которые мы заслужили.

✅ is_compound - указатели, ссылки, массивы, функции, классы и объединения, перечисления, и их cv-квалификации.

Дальше пойдут трейты, которым не удовлетворяет простая структура:

🙈 is_empty - имеет хотя бы одно нестатическое поле.

🙈 is_polymorphic - есть хотя бы одна виртуальная функция

🙈 is_fundamental_v - арифметические типы, void и std::nullptr_t.

🙈 is_scalar - все, что можно представить числом. Числа, указатели, перечисления.

В следующем посте можем обсудить, как ситуация изменится, если чуть подкрутить начальную структуру.

Know your traits. Stay cool.

#template #cppcore
  • 👍 16
  • ❤ 10
  • 🔥 8
More from @grokaemcpp
  1. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  2. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  3. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  4. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  5. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
  6. Sep 25, 2026​​std::spanstream #опытным Радостная весть для всех, кто пользуется iostreams! В C++23 доб…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →