Устаревший неявно объявленный конструктор копирования - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь обернуть голову странной характеристикой неявно объявленных конструкторов копирования.Возьмите следующий пример.Как только пользователь реализует собственный деструктор, конструктор копирования больше не является тривиальным, но все еще генерируется.

#include <type_traits>
#include <cstdio>

struct test {
    test() = default;
    ~test() {
    }
    test(const test&) = default;
    int i{42};
};
static_assert(std::is_copy_constructible_v<test>, "werks"); // OK
static_assert(std::is_trivially_copy_constructible_v<test>, "sad"); // FAILS

int main() {
    test t;
    test t2(t);
    printf("%d\n", t2.i);
    return 0;
}

Онлайн-версия: https://godbolt.org/z/t-8_W3

Я понимаю тривиальные конструкторыони генерируются компилятором.Однако cppreference сообщает:

Генерация неявно определенного конструктора копирования не рекомендуется, если в T есть пользовательский деструктор или пользовательский оператор назначения копирования.

Итак, кажется, есть еще одно состояние, в котором может быть неявно объявленный конструктор, которое является "устаревшим".Это не "тривиально" и не реализовано пользователем, но все еще генерируется вашим компилятором ... Это правильно?Кто-нибудь знает черту типа или обходной путь, чтобы проверить, является ли конструктор "устаревшим"?

1 Ответ

0 голосов
/ 27 сентября 2018

is_trivially_copy_constructible<T> также требует, чтобы T был тривиально разрушаем.Эта черта проверяется, если определение гипотетической переменной:

T t(declval<T const&>());

не вызовет нетривиальных операций.Но test не является тривиально разрушаемым, и это разрушение подразумевается в этой конструкции.

Если вы измените ~test() { } на ~test() = default, утверждение больше не будет срабатывать.

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

...