Может ли T иметь деструктор, если std :: is_trivial_v <T>имеет значение true? - PullRequest
0 голосов
/ 14 апреля 2020
#include <type_traits>

struct A
{
    ~A() {}
};

int main()
{
    static_assert(std::is_trivial_v<A>); // error   
}

Кажется очевидным, что std::is_trivial_v<A> будет false, если A имеет деструктор.

Однако со страницы cppref из std::is_trivial есть ничего, требующего A, не должно иметь деструктора.

Может ли T иметь деструктор, если std::is_trivial_v<T> истинно?

Ответы [ 3 ]

8 голосов
/ 14 апреля 2020

Вам нужно go дальше по кроличьей норе. На странице cppreference сказано, что тривиальные типы должны быть TriviallyCopyable . Если вы посещаете эту страницу, значит, ей нужен

Тривиальный неразрушенный деструктор

, и если мы перейдем по этой ссылке, у нас будет

Тривиальный деструктор

Деструктор для класса T тривиален, если выполняется все следующее:

  • Деструктор не предоставлен пользователем (то есть, он либо неявно объявлен, либо явно определен как дефолтный в его первом объявлении)
  • Деструктор не является виртуальным (то есть деструктор базового класса не является виртуальным)
  • Все прямые базовые классы имеют тривиальные деструкторы
  • Все нестатические c члены данных типа класса (или массива типа класса) имеют тривиальные деструкторы

Тривиальный деструктор - это деструктор, который не выполняет никаких действий. Объекты с тривиальными деструкторами не требуют выражения удаления и могут быть удалены простым освобождением их хранилища. Все типы данных, совместимые с языком C (типы POD), являются тривиально разрушаемыми.

Так что, да, ему нужен тривиальный деструктор, и ваш пользователь, если пустой, не считается тривиальным.

Единственный способ «написать» деструктор и считать его тривиальным - это использовать

~ClassName() = default;
2 голосов
/ 14 апреля 2020

Когда тип тривиален, это означает, что он может быть тривиально уничтожен.
Явное определение метода, как вы это сделали, не будет соответствовать этому ограничению.
Но то, что вы можете сделать, это:

struct A {
    ~A() = default;
};

static_assert(std::is_trivial<A>::value);
2 голосов
/ 14 апреля 2020

Может ли T иметь деструктор, если std::is_trivial_v<T> истинно?

У него не может быть нетривиального деструктора. Деструктор для класса T тривиален, если выполняются все следующие условия:

  • Деструктор не предоставляется пользователем (имеется в виду, что он либо неявно объявлен, либо явно определен как дефолтный для его первое объявление)
  • Деструктор не является виртуальным (то есть деструктор базового класса не является виртуальным)
  • Все прямые базовые классы имеют тривиальные деструкторы
  • Все нефиксированные c члены данных типа класса (или массива типа класса) имеют тривиальные деструкторы
...