Рассмотрим следующую программу:
#include <iostream>
#include <utility>
class T {
public:
T() { printf("address at construction: %zx\n", (uintptr_t)this); }
// T(const T&) { printf("copy-constructed\n"); } // helps
// T(T&&) { printf("move-constructed\n"); } // helps
// T(const T&) = default; // does not help
// T(T&&) = default; // does not help
};
T f() { return T(); }
int main() {
T x = f();
printf("address after construction: %zx\n", (uintptr_t)&x);
return 0;
}
Компиляция с g++ -std=C++17 test.cpp
дает следующий результат (то же самое с clang++
):
address at construction: 7ffcc7626857
address after construction: 7ffcc7626887
На основе ссылки C++ я ожидал, что программа выведет два равных адреса, потому что копия/перемещение должны быть гарантированы (по крайней мере, в C++ 17).
Если я явно определяю либо копию, либо конструктор перемещения, либо оба (см. Пронумерованные строки в примере), программа дает ожидаемый результат (даже с C++ 11):
address at construction: 7ffff4be4547
address after construction: 7ffff4be4547
Просто настройка конструктора копирования/перемещения по default
не помогает.
Ссылка явно заявляет
[Конструкторы копирования/перемещения] не должны присутствовать или доступны
Так что мне здесь не хватает?