Почему мой конструктор перемещения по умолчанию не исключение? - PullRequest
27 голосов
/ 22 января 2020

Согласно ответу на этот вопрос , конструктор перемещения по умолчанию можно определить как noexcept при определенных условиях. Например, следующий класс генерирует конструктор перемещения noexcept:

class C {};

В соответствии с ответом на этот вопрос конструктор перемещения, определенный с помощью спецификатора = default, сгенерирует тот же, что и неявно определенный конструктор перемещения. Так что, если я правильно понимаю, следующий класс должен сгенерировать noexcept конструктор перемещения:

class D {
    D(D&&) = default;
};

Чтобы проверить это, я использовал функцию std::is_nothrow_move_constructible, чтобы проверить, если C и D есть noexcept конструктор перемещения:

#include <type_traits>

int main() {
    static_assert(std::is_nothrow_move_constructible<C>::value, "C should be noexcept MoveConstructible");
    static_assert(std::is_nothrow_move_constructible<D>::value, "D should be noexcept MoveConstructible");

    return 0;
}

Когда я компилирую, я получаю эту ошибку:

$ g++ toy.cpp -o toy
toy.cpp: In function ‘int main()’:
toy.cpp:16:5: error: static assertion failed: D should be noexcept MoveConstructible
     static_assert(std::is_nothrow_move_constructible<D>::value, "D should be noexcept MoveConstructible");
     ^~~~~~~~~~~~~

Почему мой D конструктор перемещения не noexcept?


Я также пытался с Clang, и я получаю ту же ошибку. Вот информация о моих компиляторах:

$ g++ --version
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ clang++8 --version
clang version 8.0.0 
Target: x86_64-unknown-linux-gnu
Thread model: posix

Ответы [ 2 ]

30 голосов
/ 22 января 2020

На самом деле это не имеет ничего общего с noexcept; static_assert также не будет работать с std::is_move_constructible, потому что конструктор перемещения - private. Так что просто объявите это как public.

class D {
public:
    D(D&&) = default;
};

LIVE с Clang8

12 голосов
/ 22 января 2020

Я считаю, что проблема в том, что вы по умолчанию использовали конструктор перемещения D private . Попробуйте сделать это publi c.

...