Как работает сопоставление функций при использовании семантики перемещения и копирования? - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть некоторые неоднозначности относительно семантики "перемещения": я прочитал, что конструктор или назначение перемещения неявно определяется как удаленная функция, если класс определил один из своих собственных элементов управления копированием. Но у меня есть этот код:

int main()
{
    struct A {
        A() = default;
        A(const A&) { cout << "A's cpy-ctor\n"; } // this forces move ctor to be defined as a deleted function
        //A(A&&) = default;
        //A(A&&) = delete; // if uncomment this line then the line below calling std::move will cause an error(referencing a deleted function).
    };

    A a = std::move(A{}); // move not available then use copy-ctor instead


    std::cout << "\ndone\n";
}
  • Если я раскомментирую первую закомментированную строку, то все в порядке, как я уже догадался: вместо move-ctor используется конструктор копирования как факт, это явно не определено.

    • Но если я раскомментирую вторую закомментированную строку, я получу ошибку во время компиляции при вызове std :: move с жалобой на удаленную функцию. Но почему компилятор не использует copy-ctor вместо этого напрямую?

    • Что означает отключение этого move-ctor и как это влияет на сопоставление функций?

Большое спасибо!

1 Ответ

1 голос
/ 03 февраля 2020

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

Это означает, что единственной действительной подписью является A(A const &) - конструктор копирования.

Итак, когда вы вызываете конструктор со ссылкой на rvalue (что явно указано в std :: move), лучшим будет конструктор копирования, подпись которого является ссылкой на lvalue для const. match.

Однако, если вы определили конструктор перемещения как удаленный, то эта сигнатура будет найдена, и, поскольку это лучшее совпадение, компилятор даже не попытается сопоставить его с конструктором копирования. Однако, поскольку конструктор перемещения удален, компилятор говорит: «эй, я нашел наилучшее совпадение, то есть конструктор перемещения, поэтому я воспользуюсь им, но он определен как удаленный, поэтому вы не можете его вызывать. «

...