Какая функция может изменить параметр, передаваемый по значению в C ++?

В основном это вопрос о семантике. Я использую библиотеку Cereal для (де) сериализации в C ++, и мне показался интересным ее стиль кодирования:

cereal::PortableBinaryInputArchive ar(instream);
int out;
ar(out);
// int is successfully deserialized from input stream here.

Сложность состоит в том, что я не передаю «out» по ссылке, и ar () все еще может изменить его значение. На самом деле автор просто переопределяет оператор «()». И я нашел соответствующие строки в исходных файлах.

OutputArchive & operator=( OutputArchive const & ) = delete;

//! Serializes all passed in data
/*! This is the primary interface for serializing data with an archive */
template <class ... Types> inline
ArchiveType & operator()( Types && ... args )
{
self->process( std::forward<Types>( args )... );
return *self;
}

Я в полном недоумении, особенно первая строка («= delete») и вещи, касающиеся «std :: forward (args) …». Я видел только некоторые случаи, когда использовались макросы типа va_arg, и я впервые столкнулся с чем-то подобным. Кроме того, что значит «&&»стоять за? Может ли кто-нибудь пролить свет на это?

1

Решение

Я в растерянности, особенно первая строка («= delete»)

«= Delete» эффективно гарантирует, что operator = (оператор присваивания …) не может быть вызван, и что значение по умолчанию (оператор присваивания) не должно генерироваться. Это то же самое, что делает operator = private и не дает определения. Этот оператор также может использоваться для обычных функций, в этом случае его использование аналогичным образом запрещено (см. Стандарт c ++ 11, раздел 8.4.3):

struct B
{
void foo(){}
};

struct D : B
{
void foo() = delete;
};

int main() {
D().foo(); //Fails to compile here - deliberate!!!
return 0;
}

Обратите внимание, что тип, для которого вызывается foo, важен. Он по-прежнему может вызываться для базового типа, точно так же, как можно порезать, даже если производное присваивание запрещено (см. Пример ниже):

struct B{};

struct D : B
{
D& operator=(const D&) = delete;
};

int main() {
B b;
D d1, d2;
b = d1; //Compiles fine - slices
d1 = d2; //Fails to compile...
return 0;
}

и что касается «std :: forward (args) …».

std :: forward позволяет совершенную пересылку аргументов (то есть типы аргументов относительно значения r / l и модификаторы не меняются (См).

Я видел только некоторые случаи, когда
используются такие макросы, как va_arg, и я впервые
столкнулся с чем-то вроде этого.

template <class ... Types>
void foo( Types&& ...);

… в этом контексте упоминается как шаблоны с переменным числом (google).

Кроме того, что значит «&&»стоять за?
Может ли кто-нибудь пролить свет на это?

&& обозначает либо ссылку на значение, либо универсальную ссылку, в зависимости от контекста. В данном случае это универсальная ссылка (у Скотта Мейерса есть хорошая статья об универсальных ссылках Вот).

РЕДАКТИРОВАТЬ:
Универсальные ссылки теперь правильно называются пересылочными ссылками (N4164).

4

Другие решения


По вопросам рекламы [email protected]