C++ 对函数的直观理解引用的引用
可能重复:C++ 对函数的直观理解引用的引用,c++,pass-by-reference,rvalue-reference,c++11,C++,Pass By Reference,Rvalue Reference,C++11,可能重复: 出于某种原因,这是我的直觉,我无法在互联网上找到任何解释。C++函数引用引用的含义是什么?例如: void myFunction(int&& val); //what does this mean?! 我理解通过引用传递的想法,所以 void addTwo(int& a) { a += 2; } int main() { int x = 5; addTwo(x); return 0; } 这不是引用的引用,而是
出于某种原因,这是我的直觉,我无法在互联网上找到任何解释。C++函数引用引用的含义是什么?例如:
void myFunction(int&& val); //what does this mean?!
我理解通过引用传递的想法,所以
void addTwo(int& a)
{
a += 2;
}
int main()
{
int x = 5;
addTwo(x);
return 0;
}
这不是引用的引用,而是一种称为的新语言功能,它(非正式地)表示对内存中某个对象的引用,该对象在程序的其他地方没有引用,可以进行破坏性修改。例如,右值引用可以捕获函数的返回值,表达式中引入的临时值也可以捕获 右值引用可用于多种用途。从大多数C++程序员的角度来看,它们可以被用来实现,从而可以通过“移动”旧对象的内容从旧对象和新对象初始化新的对象。您可以使用它从C++11中的函数返回巨大的对象,而无需支付复制该对象的巨大成本,因为用于捕获返回值的对象可以使用move构造函数初始化,只需从return语句创建的临时对象中窃取内部内容 移动语义与复制语义正交,因此对象可以在不可复制的情况下移动。例如,
std::ofstream
s是不可复制的,但它们是可移动的,因此您可以使用移动行为从函数返回std::ofstream
s。这在C++03中目前无法完成。例如,此代码在C++03中是非法的,但在C++11中却非常好(并受到鼓励!):
std::ifstream GetUserFile() {
while (true) {
std::cout << "Enter filename: ";
std::string filename;
std::getline(std::cin, filename);
ifstream input(filename); // Note: No .c_str() either!
if (input) return input;
std::cout << "Sorry, I couldn't open that file." << std::endl;
}
}
std::ifstream file = GetUserFile(); // Okay, move stream out of the function.
需要注意的是,当我们在构造函数末尾清除rhs
时,我们最终将rhs
置于这样一种状态,即
nullptr
,因为释放nullptr
是安全的),并且template <typename T> void swap(T& lhs, T& rhs) {
T temp = lhs;
lhs = rhs;
rhs = temp;
}
现在,根本没有复制品。我们将
lhs
的内容移动到temp
,然后将rhs
的内容移动到lhs
,然后将temp
的内容移动到rhs
。在这样做时,我们将lhs
和rhs
暂时置于“清空”状态,然后再将新值放入其中。重要的是,在编写代码以将内容移出对象时,我们要使对象保持某种格式良好的状态,以便此代码正常工作。它不是对引用的引用。这是C++0x中引入的一种新语法,用于所谓的。您能提供一个简单的代码示例来演示它的用法吗?@Daniel-是的,刚刚做了!如果还有什么我可以澄清的,请告诉我!只需确保在被“破坏性修改”之后,类必须仍然有效。重要的一点是:它仍然应该是可破坏的,并且是可分配的。@mooingduck-谢谢你指出这一点!我刚刚更新了答案来解释这一点以及为什么它是必要的。非常好地解释了右值引用的使用@弗雷德:我赞成保留这两个选项的开放性,重复你提到的问题的答案使用了标准化的语言,而templatetypedef下面的答案用外行的术语给出了一个简洁的解释(但不是真正的定义)。@Matthieu:问题(和答案)不能合并,因为它们是同一个问题吗?我们不应该让两个相同的问题悬而未决。
template <typename T> void swap(T& lhs, T& rhs) {
T temp = lhs;
lhs = rhs;
rhs = temp;
}
template <typename T> void swap(T& lhs, T& rhs) {
T temp = std::move(lhs);
lhs = std::move(rhs);
rhs = std::move(temp);
}