Не получена ошибка времени компиляции после удаления конструкторов копирования / перемещения и операторов присваивания при передаче объекта в функцию - PullRequest
0 голосов
/ 18 ноября 2018

В следующем коде я явно запретил копирование и перемещение объекта Dummy с использованием спецификатора delete для конструкторов копирования и перемещения и операторов копирования и перемещения:

#include <string>
#include <iostream>

struct Dummy
{
    explicit Dummy(const std::string& value) : value_(value) {}
    Dummy(const Dummy&) = delete;
    Dummy& operator=(const Dummy&) = delete;
    Dummy(Dummy&&) = delete;
    Dummy& operator=(Dummy&&) = delete;

    void print_this_address() const
    {
        std::cout << "this address: " << this << "\n";
    }

    std::string value_;
};

void foo(Dummy&& obj)
{
    std::cout << obj.value_ << "\n";
    obj.print_this_address();
}

int main()
{
    Dummy obj("42");
    obj.print_this_address();
    foo(std::move(obj));
    std::cout << obj.value_ << "\n";
    return 0;
}

Этот код компилируется и выполняетсяхорошо, и я получаю следующий вывод в моем терминале:

this address: 0x7ffeeb6d2a20
42
this address: 0x7ffeeb6d2a20
42

Может кто-нибудь объяснить мне, что происходит в этом коде и почему я не получил ошибку компиляции и у меня тот же объект в fooфункционировать как в main.функционировать?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

На самом деле вы никогда не пытаетесь скопировать или переместить объект, поэтому вы не получаете сообщение об ошибке.

Параметр Dummy &&obj является ссылочным параметром rvalue, то есть может связываться с rvalue, но нек значениям.Это по-прежнему ссылка, точно так же, как const Dummy &obj (что также будет работать в вашем случае).

То, что делает std::move, - это не перемещать что-либо, а преобразовывает свой параметр в ссылку на rvalue.Это позволяет передавать его функциям, ожидающим значение r (например, конструктор перемещения).Для получения более подробной информации посмотрите ответ, связанный StoryTeller .

0 голосов
/ 18 ноября 2018

Это не потому, что вы назвали std::move, что ваш объект переместился.Он был просто «подготовлен» для перемещения.

Таким образом, вы подготовили obj, но никогда не пытались переместить его куда-то еще, следовательно, нет ошибки компилятора, и, поскольку вы никогда не перемещали его (вы просто передалиЕсли указать ссылку на ваш объект в foo), вы получите тот же результат, потому что obj никогда не менялся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...