函数如何修改C++中按值传递的参数?
How can a function modify a parameter passed in by value in C++?
基本上这是一个关于语义的问题。我在 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++ 中使用 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)。