在线文档教程
C++
语言 | Language

Reference declaration

参考声明

将命名变量声明为引用,即已存在对象或函数的别名。

句法

引用变量声明是指其报关员有表格。

& attr(optional) declarator(1)
&& attr(optional) declarator(2)(since C++11)

1%29Lvalue引用声明器*宣言S& D;宣告D作为值参考指定符-seq所确定的类型。S...

2%29Rvalue引用声明器*宣言S&& D;宣告D作为R值参考指定符-seq所确定的类型。S...

declarator-any declarator except another reference declarator (there are no references to references)
attr(C++11)-optional list of attributes

引用需要初始化才能引用有效的对象或函数:参考初始化...

没有提到void也没有提到参考资料。

引用类型不能简历-合格在顶层,声明中没有这种语法,如果通过tyduf、dectype或模板类型参数引入限定,则忽略它。

引用不是对象;它们不一定占用存储空间,不过如果需要实现所需的语义%28e.g,编译器可能会分配存储空间。引用类型的非静态数据成员通常会将类的大小增加到存储内存地址%29所需的数量。

因为引用不是对象,所以没有引用数组,没有指向引用的指针,也没有对引用的引用:

二次

int& a[3]; // error int&* p; // error int& &r; // error

二次

Reference collapsing It is permitted to form references to references through type manipulations in templates or typedefs, in which case the reference collapsing rules apply: rvalue reference to rvalue reference collapses to rvalue reference, all other combinations form lvalue reference: typedef int& lref; typedef int&& rref; int n; lref& r1 = n; // type of r1 is int& lref&& r2 = n; // type of r2 is int& rref& r3 = n; // type of r3 is int& rref&& r4 = 1; // type of r4 is int&& (This, along with special rules for template argument deduction when T&& is used in a function template, forms the rules that make std::forward possible.).(since C++11)

Lvalue引用

Lvalue引用可用于将现有对象%28化成别名,可以选择使用不同的cv-资格%29:

二次

#include <iostream> #include <string> int main() { std::string s = "Ex"; std::string& r1 = s; const std::string& r2 = s; r1 += "ample"; // modifies s // r2 += "!"; // error: cannot modify through reference to const std::cout << r2 << '\n'; // prints s, which now holds "Example" }

二次

它们还可用于在函数调用中实现按引用传递语义:

二次

#include <iostream> #include <string> void double_string(std::string& s) { s += s; // 's' is the same object as main()'s 'str' } int main() { std::string str = "Test"; double_string(str std::cout << str << '\n'; }

二次

当函数%27s返回类型为lvalue引用时,函数调用表达式变为lvalue表达式*

二次

#include <iostream> #include <string> char& char_number(std::string& s, std::size_t n) { return s.at(n // string::at() returns a reference to char } int main() { std::string str = "Test"; char_number(str, 1) = 'a'; // the function call is lvalue, can be assigned to std::cout << str << '\n'; }

二次

Rvalue references Rvalue references can be used to extend the lifetimes of temporary objects (note, lvalue references to const can extend the lifetimes of temporary objects too, but they are not modifiable through them): #include #include int main() { std::string s1 = "Test"; // std::string&& r1 = s1; // error: can't bind to lvalue const std::string& r2 = s1 + s1; // okay: lvalue reference to const extends lifetime // r2 += "Test"; // error: can't modify through reference to const std::string&& r3 = s1 + s1; // okay: rvalue reference extends lifetime r3 += "Test"; // okay: can modify through reference to non-const std::cout << r3 << '\n'; } More importantly, when a function has both rvalue reference and lvalue reference overloads, the rvalue reference overload binds to rvalues (including both prvalues and xvalues), while the lvalue reference overload binds to lvalues: #include #include void f(int& x) { std::cout << "lvalue reference overload f(" << x << ")\n"; } void f(const int& x) { std::cout << "lvalue reference to const overload f(" << x << ")\n"; } void f(int&& x) { std::cout << "rvalue reference overload f(" << x << ")\n"; } int main() { int i = 1; const int ci = 2; f(i // calls f(int&) f(ci // calls f(const int&) f(3 // calls f(int&&) // would call f(const int&) if f(int&&) overload wasn't provided f(std::move(i) // calls f(int&&) // rvalue reference variables are lvalues when used in expressions int&& x = 1; f(x // calls f(int& x) f(std::move(x) // calls f(int&& x) } This allows move constructors, move assignment operators, and other move-aware functions (e.g. vector::push_back() to be automatically selected when suitable.(since C++11)

Forwarding references Forwarding references are a special kind of references that preserve the value category of a function argument, making it possible to forward it by means of std::forward. Forwarding references are either: 1) function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template: template int f(T&& x) { // x is a forwarding reference return g(std::forward(x) // and so can be forwarded } int main() { int i; f(i // argument is lvalue, calls f(int&), std::forward(x) is lvalue f(0 // argument is rvalue: calls f(int&&), std::forward(x) is rvalue } template int g(const T&& y // y is not a forwarding reference: const T is not exactly T template struct A { template A(T&& x, U&& y, int* p // x is not a forwarding reference, but y is }; 2) auto&& except when deduced from a brace-enclosed initializer list. auto&& vec = foo( // foo() may be lvalue or rvalue, vec is a forwarding reference auto i = std::begin(vec // works either way (*i)++; // works either way g(std::forward(vec) // forwards, preserving value category for(auto&& x: f()) { // x is a forwarding reference; this is the safest way to use range for loops } auto&& z = {1,2,3}; // *not* a forwarding reference (special case for initializer lists) See also template argument deduction and std::forward.(since C++11)

悬空引用

虽然一旦初始化了引用,总是引用有效的对象或函数,但是可以创建一个程序,其中寿命对象的引用,但引用仍然是可访问的%28。悬吊29%。访问这样的引用是未定义的行为。一个常见的示例是一个函数,它返回一个自动变量的引用:

二次

std::string& f() { std::string s = "Example"; return s; // exits the scope of s: // its destructor is called and its storage deallocated } std::string& r = f( // dangling reference std::cout << r; // undefined behavior: reads from a dangling reference std::string s = f( // undefined behavior: copy-initializes from a dangling reference

二次

注意,对Const的rvalue引用和lvalue引用延长了临时对象的生存期%28(参见参照系[医]初始化#寿命[医]成[医]阿[医]暂时性对于规则和例外情况,%29。

如果所引用的对象已被销毁,则为%28例如。通过显式析构函数调用%29,但是存储没有被释放,对过期对象的引用可能会以有限的方式使用,并且如果在同一个存储区%28中重新创建对象,则可能会生效。生命期外访问详情见%29。

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/Reference