powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамическое включение/отключение конструкторов/операторов присваивания в классе
8 сообщений из 8, страница 1 из 1
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #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
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #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
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #40050019
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
То что тут ошибка вообще похоже на баг

проверял на двух компиляторах: clang и msvc - везде одинаково :)
...
Рейтинг: 0 / 0
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #40050020
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
судя по всему, это поведение by design и его никак не обойти
...
Рейтинг: 0 / 0
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #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
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #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
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #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
Динамическое включение/отключение конструкторов/операторов присваивания в классе
    #40057501
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum, специализация шаблонов нынче не в фаворе?
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Динамическое включение/отключение конструкторов/операторов присваивания в классе
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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