Самый краткий способ отключить семантику копирования и перемещения
следующее, конечно, работает, но очень утомительно:
T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
Я пытаюсь найти самый краткий способ. Будут следующие работы?
T& operator=(T) = delete;
обновление
обратите внимание, что я выбираю T& operator=(T)
вместо T& operator=(const T&)
или T& operator=(T&&)
, потому что он может служить обеим целям.
5 ответов
согласно этой диаграмме (Говард Хиннант):
самый краткий путь =delete
оператор назначения перемещения (или конструктор перемещения, но это может вызвать проблемы, упомянутые в комментариях).
хотя, на мой взгляд, самый читабельный путь =delete
и копирующий конструктор и копирующий оператор присваивания.
Я предпочитаю наследовать от boost:: noncopyable, тем самым делая намерение немедленно ясным и делегируя детали надежной библиотеке.
#include <boost/core/noncopyable.hpp>
class X: private boost::noncopyable
{
};
Это включает в себя добавление зависимости, но если вы в порядке с этим, это, возможно, очень краткий и выразительный способ ее выполнения.
пожалуйста, не пытайтесь найти "самый краткий способ" написать фрагмент кода.
Если нет очевидной формы выражения чего - то, что также очень лаконично-Не ищите, не пытайтесь формулировать-адвокат Ваш путь к написанию нескольких символов меньше. Почему? Подумайте о людях, читающих ваш код:
Если вам нужно проконсультироваться со стандартом, чтобы понять, что ваш код делает то, что вы хотите, чтобы он делал - то и читатели вашего кода. Только они не поймут, что ты пытаешься сделать. чтобы достичь; поэтому они не будут консультироваться со стандартом; поэтому они просто будут смущены тем, что делает ваш код. Или-кто-то получит, а кто-то нет.*1
в вашем случае, если вы сделаете подмножество этих удалений или используете какой - то другой "умный" трюк-как человек, читающий ваш код, я, скорее всего, не поймаю, не замечу, что вы на самом деле пытаетесь удалить всю семантику копирования и перемещения. И я запутаюсь, думая, что ты пытаешься сделать что-то еще. На самом деле, если я будь вы, я бы даже подумал добавить комментарий, говоря:
/* Disabling copy and move semantics because XYZ */
T(const T&) = delete;
T(T&&) = delete;
T& operator=(const T&) = delete;
T& operator=(T&&) = delete;
что еще более "утомительно", но сделает ваше намерение/мотивацию абсолютно ясными для ваших будущих читателей.
существует также вопрос о том, что именно является причиной "XYZ". Некоторые утверждают, что нет веских причин удалять члены move, и это, как правило, плохая идея сделать это. C++ luminary Говард Хиннант имеет сказал по этому вопросу.
* - A вариант по принципу я прописал здесь.
вы можете написать простой struct
и наследовать от него:
struct crippled
{
crippled() = default;
crippled(const crippled&) = delete;
crippled(crippled&&) = delete;
crippled& operator=(const crippled&) = delete;
crippled& operator=(crippled&&) = delete;
};
использование:
struct my_class : crippled
{
};
int main()
{
my_class a;
auto b = a; // fails to compile
}
Я считаю, что в этом случае макросы на самом деле более читабельным:
#define NOT_COPYABLE( TypeName ) \
TypeName ( TypeName const& ) = delete; \
TypeName & operator = ( TypeName const& ) = delete;
#define NOT_MOVEABLE( TypeName ) \
TypeName ( TypeName && ) = delete; \
TypeName & operator = ( TypeName && ) = delete;