Гость
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамическое включение/отключение конструкторов/операторов присваивания в классе / 8 сообщений из 8, страница 1 из 1
02.03.2021, 12:51
    #40049800
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Всем привет!

Пишу шаблонный класс, в котором хочу определять его семантику копирования/перемещения в зависимости от типа шаблонного аргумента.

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

Это очень упрощенное описание реальной задачи, но его достаточно для обозначения проблемы.
В целом у меня все получается и работает как задумано, кроме одного момента (убрал все шаблонное, чтобы не усложнять).
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
struct copy_only // объекты данного класса можно только копировать
{
	copy_only(void) = default;
	copy_only(copy_only&&) noexcept = delete;
	copy_only& operator=(copy_only&&) noexcept = delete;
	copy_only(const copy_only& that) = default;
	copy_only& operator=(const copy_only& that) = default;
};

struct move_only // объекты данный класса можно только перемещать
{
	move_only(void) = default;
	move_only(const move_only& that) = delete;
	move_only(move_only&& that) noexcept = default;
	move_only& operator=(const move_only&) = delete;
	move_only& operator=(move_only&& that) noexcept = default;
};

// создадим на их основе производные классы, семантика которых будет определяться базовыми классами.
// если базовый класс умеет только копироваться, то и производный тоже можно только копировать, и наоборот

struct derived_from_move : move_only {};
struct derived_from_copy : copy_only {};


Проблема вот в чем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int main()
{
	derived_from_move dmove;
	auto gc = dmove;		// ошибка: попытка обращения к delete функции в классе move_only - good!
	auto gm = std::move(dmove);	// ок

	derived_from_copy dcopy;
	auto xc = dcopy;		// ок
	auto xm = std::move(dcopy);	// ок (why!?) <- я хочу чтобы здесь была такая же ошибка как у класса derived_from_move

	copy_only co;
	auto cx = std::move(co);	// ошибка - good! хочу также
}


пощупать пример вживую

Если я буду использовать класс copy_only напрямую, без derived_from_copy, то поведение будет корректным с ожидаемой ошибкой.
Я знаю почему это происходит (с точки зрения move-семантики copy-only объекта), но мне бы хотелось реализовать это поведение, по аналогии с тем как работает тип copy_only или как derived_from_move.

Что посоветуете?

--------------------------------------------------------------
o(O_O)o
...
Рейтинг: 0 / 0
02.03.2021, 18:29
    #40049961
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Cerebrum
Код: plaintext
1.
2.
	copy_only co;
	auto cx = std::move(co);	// ошибка - good! хочу также



То что тут ошибка вообще похоже на баг, потому что по логике если объект копируемый то его можно скопировать из какой угодно ссылки в т.ч. и rvalue.

Более того,
https://en.cppreference.com/w/cpp/language/overload_resolution

Defaulted move constructor and move assignment that are defined as deleted are never included in the list of candidate functions.

Inherited copy and move constructors are not included in the list of candidate functions when constructing a derived class object.
Из этих двух абзацев следует что как для derived_from_copy так и copy_only, move ctor исключается из списка кандидатов при поиске перегрузки, а значит он не может предовратить вызов copy ctor .

Кстати вот этот код работает без ошибки, а там тоже создается копия из rvalue ссылки :)
Код: plaintext
1.
2.
    copy_only func();
    auto cx = func();
...
Рейтинг: 0 / 0
02.03.2021, 20:28
    #40050019
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Anatoly Moskovsky
То что тут ошибка вообще похоже на баг

проверял на двух компиляторах: clang и msvc - везде одинаково :)
...
Рейтинг: 0 / 0
02.03.2021, 20:29
    #40050020
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
судя по всему, это поведение by design и его никак не обойти
...
Рейтинг: 0 / 0
03.03.2021, 00:12
    #40050071
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Anatoly Moskovsky
Cerebrum
Код: plaintext
1.
2.
	copy_only co;
	auto cx = std::move(co);	// ошибка - good! хочу также


То что тут ошибка вообще похоже на баг, потому что по логике если объект копируемый то его можно скопировать из какой угодно ссылки в т.ч. и rvalue.
Не существует никакого "копирования из ссылки". Не путай rvalue и rvalue reference.
Anatoly Moskovsky
Более того,
https://en.cppreference.com/w/cpp/language/overload_resolution

Defaulted move constructor and move assignment that are defined as deleted are never included in the list of candidate functions.

Inherited copy and move constructors are not included in the list of candidate functions when constructing a derived class object.

Из этих двух абзацев следует что как для derived_from_copy так и copy_only, move ctor исключается из списка кандидатов при поиске перегрузкиmove-constructor у copy_only не defaulted. Так что первое предложение к copy_only не применимо. Оно применимо только к derived_from_copy.
А зачем сюда приплетено inherited copy/move constructors — это вообще непонятно. Вот что такое inherited constructors:
Код: plaintext
1.
2.
3.
4.
struct B {};
struct D : B {
    using B::B; // inherited constructors
};


Anatoly Moskovsky
Кстати вот этот код работает без ошибки, а там тоже создается копия из rvalue ссылки :)
Код: plaintext
1.
2.
    copy_only func();
    auto cx = func();

Если в случае std::move rvalue-ссылка есть хотя бы в возвращаемом типе, то в случае func() ссылок нет вообще нигде.
И до C++17 ошибка есть .
...
Рейтинг: 0 / 0
03.03.2021, 13:00
    #40050260
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
авторDefaulted move constructor and move assignment that are defined as deleted are never included in the list of candidate functions.
a guest
move-constructor у copy_only не defaulted. Так что первое предложение к copy_only не применимо. Оно применимо только к derived_from_copy.

Тогда напишите что такое "Defaulted move constructor defined as deleted".
...
Рейтинг: 0 / 0
03.03.2021, 21:16
    #40050464
a guest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Anatoly Moskovsky
что такое "Defaulted move constructor defined as deleted".
Так сложно открыть предметный указатель в стандарте и найти там слово "defaulted"?
C++20 [dcl.fct.def.default]/5Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functionsExplicitly-defaulted это
C++20 [dcl.fct.def.default]/1A function definition whose function-body is of the form
Код: plaintext
1.
= default ;

is called an explicitly-defaulted definition.
Это
Код: plaintext
1.
copy_only(copy_only&&) noexcept = delete;

explicitly-defaulted или implicitly-declared, чтобы быть defaulted?

Про то, когда defaulted defined as deleted можно почитать в [class.copy.ctor].
...
Рейтинг: 0 / 0
28.03.2021, 05:01
    #40057501
rdb_dev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Динамическое включение/отключение конструкторов/операторов присваивания в классе
Cerebrum, специализация шаблонов нынче не в фаворе?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамическое включение/отключение конструкторов/операторов присваивания в классе / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]