Запрещение move конструктора

171
12 февраля 2019, 18:20

Почему следующий код работает, хотя я явно удалил move конструктор?

class X {
public:
    X() = default;
    X(const X&) = delete;
    X(X&&) = delete;
    int val = 42;
};
template<typename T>
int foo(T x) {
    return x.val;
}

int main() {
    X x1;
    //X x2{x1}; // error
    //X x3{std::move(x1)}; // error
    //foo(x1); // error
    //foo(std::move(x1)); //error
    foo(X{}); // OK?
}

Какие ограничения налагаются на тип T кроме того, что он должен иметь member val, приводимый к int? Можно ли запретить последнюю передачу?

Answer 1

Потому что в строчке foo(X{}); нет ни копирования, ни перемещения. Есть материализация prvalue в объект с именем x. Материализация, как может быть понятно из самого термина, это прямое создание объекта из prvalue, без каких либо промежуточных копирований/перемещений. Запретить это нельзя, это «вшито» в стандарт C++17.

Подробнее я писал об этом здесь.

READ ALSO
Стандартный аналог __attribute__ ((constructor))

Стандартный аналог __attribute__ ((constructor))

Существует ли стандартный аналог конструкции gcc:

188
Как recv() понимает, что все данные получены в случаи TCP?

Как recv() понимает, что все данные получены в случаи TCP?

Насколько я понимаю, данные через TCP передаются как сплошной поток, до тех пор пока соединение не будет разорваноЕсли посмотреть на структуру...

164
как вызвать метод одного класса из другого класса

как вызвать метод одного класса из другого класса

Необходимо вызвать метод объекта ob2 из метода exe объекта ob1, используя ссылку, находящуюся в векторе объекта ob1

254