左值引用聲明: & attr(optional) declarator (1)
右值引用聲明: && attr(optional) declarator (2) (since C++11)
–1. 左值引用可以理解為對象的別名, 左值引用必須被初始化而且不能被重新賦值.
#include
#include
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"
}
–2. 在調用函數時,可以被用來作為引用參數.
#include
#include
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';
}
–3. 當一個函數的返回值是左值時, 這個函數的調用的表達式可以被認為是一個左值表達式.
#include
#include
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';
}
–1. 右值引用聲明可以區別一個左值和右值.
–2. 右值引用直至Move語義的實現, 它可以把臨時對象(一般不能引用)的資源移動到其他地方去.
–3. 右值引用也可以用來擴展臨時對象的生命周期,
#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';
}
–4. 如果函數有左值和右值引用的重載,調用時會匹配調用, 傳左值調用左值重載, 右值調用右值重載. 這樣就可以支持Move Constructor 和 Move Assignment 的實現.
#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&&)
}