问题描述
我正在学习通过引用传递,这是我所做的测试:
I was learning passing by reference, and here is the test I did:
#include <iostream>
using namespace std;
int i = 0;
//If this is uncommented, compiler gives ambiguous definition error.
//void paramCheck (string s) {
// cout << ++i << ". Param is var.\n";
//}
void paramCheck (const string& s) {
cout << ++i << ". Param is const ref.\n";
}
void paramCheck (string& s) {
cout << ++i << ". Param is non-const ref.\n";
}
void paramCheck (const string&& s) {
cout << ++i << ". Param is const rvalue-reference.\n";
}
void paramCheck (string&& s) {
cout << ++i << ". Param is non-const rvalue-reference.\n";
}
int main(int argc, char **argv) {
//Function call test
paramCheck("");
paramCheck(string{""});
string s3{""};
paramCheck(s3);
const string s4{""};
paramCheck(s4);
//Illegal
//string& s{""};
//paramCheck(s);
const string& s5{s3};
paramCheck(s5);
string&& s6{""};
paramCheck(s6);
//Illegal
//const string&& s{s1};
//onstFP(s);
//Reference test
string a = s3;
a = "a changed s3";
cout << s3;
{
string& b = s3;
b = "b changed after assigning s3\n";
cout << "s3 is now " <<s3;
b = s4;
b = "b changed after assigning s4\n";
cout << "s3 is now " <<s3;
cout << "s4 is now " <<s4;
}
cin.get();
return 0;
}
这是我得到的结果:
1. Param is non-const rvalue-reference.
2. Param is non-const rvalue-reference.
3. Param is non-const ref.
4. Param is const ref.
5. Param is const ref.
6. Param is non-const ref.
s3 is now b changed after assigning s3
s3 is now b changed after assigning s4
s4 is now
我的问题是:
-
如果我们传递一个常量表达式,它总是会触发非-恒定的右值引用?在什么情况下它将触发常量rvalue-reference(以及s6为什么不触发它?)
If we pass a constant expression, it always triggers non-constant rvalue-reference? Under what condition it will trigger constant rvalue-reference (and why s6 is not trigging it?)
为什么非常量引用和常量rvalue-reference是非法的?
Why non-constant reference and constant rvalue-reference are illegal?
我期望a不能更改s3,但是为什么内部作用域中的b可以更改s3?如果向b分配新对象s3就是分配新引用,为什么当我为其分配s4并更改s3且之后s4为空?
I expected a cannot change s3, but why b in the inner scope can change s3? If assigning a new object s3 to b is assigning a new reference, why when I assign s4 to it and s3 got changed and s4 is empty afterwards?
很抱歉提出了太多问题...回答所有问题时,我都会加分:)引用使我的困惑从指针转移到了一个全新的水平。
Sorry for asking too many questions... I will increase the points when all questions are answered :) The reference just brings my confusion from pointer to a whole new level.
我不知道如何提高积分……所以要等2天才有资格获得赏金,然后选择答案。
I don't know how to increase the point... so will wait for 2 days till eligible for bounty then choose the answer.
推荐答案
首先执行代码
paramCheck(""); //constructs a temporary. temporaries bind to `string&&`
paramCheck(string{""}); //constructs a temporary. temporaries bind to `string&&`
string s3{""};
paramCheck(s3); //passes a reference to an existing string: `string&`
const string s4{""};
paramCheck(s4); //passes a reference to an existing string+const: `const string&`
//Illegal
//string& s{""}; //cannot assign a temporary to a non-const l-reference
//what would s refer to when the temporary "dies"?
//`const string&` would have worked though
//paramCheck(s); //passes a reference to an existing string+const: `const string&`
const string& s5{s3}; //s5 is s3, but with `const`.
paramCheck(s5); //passes a reference to an existing string+const: `const string&`
string&& s6{""}; //r-references extend the life of temporaries.
paramCheck(s6); //passes a reference to an existing strong: `string&`
//const string&& s{s1}; //temporaries can be extended by `T&&` or `const T&` only.
//Reference test
string a = s3; //a is a _copy_ of s3
a = "a changed s3"; //so changing the copy doesn't effect the origional.
cout << s3; //s3 is still blank, it hasn't changed.
{
string& b = s3; //b isn't really a "reference" to `s3`". `b` _IS_ `s3`.
b = "b changed after assigning s3\n"; //since `b` IS `s3`, this changes `s3`.
cout << "s3 is now " <<s3;
b = s4; //`b` _IS_ `s3`, so you just changed `s3` again.
b = "b changed after assigning s4\n";
cout << "s3 is now " <<s3;
cout << "s4 is now " <<s4; //s4 is still blank, it hasn't changed.
}
然后是问题:
现有对象将通过 string&
或 const string&
传递,这取决于它们是否为const。也可以将它们复制到作为 string
。临时将作为 string&&
通过,但也可以复制输入为 string
。有 种触发 const string&&
的方法,但是没有理由这样做,所以没关系。 。
Existing objects will pass as string&
or const string&
depending on if they're const or not. They can also be copied in as string
. Temporaries will pass as string&&
, but can also be copied in as string
. There are ways to trigger const string&&
, but there's no reason to do so ever, so it doesn't matter. They're shown here.
该标准明确指出,只有 const string&
和 string&&
会延长临时人员的寿命,尽管我我不确定为什么他们也没有提及 string&
和 const string&&
。
The standard specifically says that only const string&
and string&&
will extend the lives of temporaries, though I'm not certain why they didn't also mention string&
and const string&&
.
您初始化了 b
作为对 s3
的引用。不是副本,而是参考。这意味着 b
现在永远指 s3
,无论如何。当您键入 b = b在分配s3\n后已更改;
时,与 s3 = b在分配s3后已更改changed完全相同\n;
。当您键入 b = s4;
时,这与 s3 = s4
完全相同。那就是参考。它们不能被重新安置。
You initialized b
as a reference to s3
. Not a copy, but a reference. That means b
now refers to s3
forever, no matter what. when you typed b = "b changed after assigning s3\n";
, that's exactly the same as s3 = "b changed after assigning s3\n";
. When you typed b = s4;
, that's exactly the same as s3 = s4
. That's what a reference is. They cannot be "reseated".
这篇关于通过引用,常量引用,右值引用还是常量右值引用传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!