c++ - 函数如何修改C++中按值传递的参数?

标签 c++ cereal

基本上这是一个关于语义的问题。我在 C++ 中使用 Cereal 库进行(反)序列化,发现它的编码风格很有趣:

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这样的宏的情况,这是我第一次遇到这样的事情。另外,“&&”代表什么?任何人都可以阐明它吗?

最佳答案

I'm quite at a loss, especially the first line ("= 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;
}

and things regarding "std::forward( args )...".

std::forward 允许参数的完美转发(即关于 r/l 值和修饰符的参数类型不会改变 (Refer)

I only saw some cases in which macros like va_arg are used and it's the first time that I've encountered something like this.

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

在此上下文中的 ... 称为可变参数模板 (google)。

Besides, what does "&&" stand for? Could anyone throw some light upon it?

&& 代表右值引用或通用引用,具体取决于上下文。在这种情况下,它是一个通用引用(Scott Meyers 有一篇关于通用引用的好文章 here )。

编辑: 通用引用现在被正确称为转发引用 (n4164) .

关于c++ - 函数如何修改C++中按值传递的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30662624/

相关文章:

C++ CMake 编译错误 (/usr/bin/ld : cannot find <LIBRARY_NAME>)

c++ - 为加载高度图的地形创建 UV 坐标?

c++ - C++11 中的 std::nextafter() 如何产生比 std::numeric_limits::min 更小的值?

c# - Visual Studio 2017 一遍又一遍地构建项目

c++ - 来自 openCV 的 cvLoadImage() + cvShowImage() 显示一个灰色框

c++ - 如何用 Cereal 序列化 boost::uuid

c++ - 能否使用 Cereal 重新创建 Protobuf 的反序列化功能之一?

c++ - 在依赖于参数的查找(或解决方法?)之前发生模板替换的任何方式

c++ - 对 `json11::Json::dump(std::string&) const' 的 undefined reference collect2 : error: ld returned 1 exit status