考虑:
void foo(std::string& s);
在此函数内部,表达式s
是左值std::string
(不是std::string&
),因为引用在表达式中并不真正“存在”:现在考虑:
const std::string& foo(const std::string& s1, const std::string& s2)
{
return (s1.size() < s2.size() ? s1 : s2);
}
另一个问题是关于条件运算符是否在这里涉及到一个临时变量的争论(该临时变量随后会影响作为悬挂引用的foo
的返回值)。我的解释是,是的,它必须是因为:
和:
从
std::string
初始化std::string
涉及一个拷贝。但是,令我惊讶的是,海湾合作委员会(GCC)没有对悬挂的引用文件提出警告。经调查,我发现
foo
确实确实传播了所选参数的引用语义:#include <string>
#include <iostream>
using std::string;
using std::cout;
void foo(string& s1, string& s2)
{
auto& s3 = (s1.size() < s2.size() ? s1 : s2);
s3 = "what";
}
int main()
{
string s1 = "hello";
string s2 = "world";
foo(s1, s2);
cout << s1 << ' ' << s2 << '\n'; // Output: hello what
}
(live demo)通过引用传递给
s2
的原始foo
已由条件运算符选择,然后绑定(bind)到s3
并进行了修改。没有任何复制正在进行的证据。这与我对表达式如何工作以及条件运算符如何工作的理解不符。
那么,我上面的哪些陈述是不正确的,为什么?
由于似乎有些困惑,因此在下面我示意了我的理解是事件链。我意识到这是错误的-以上我的测试案例证明了这一点。但我想确切地了解原因。理想情况下,我希望使用一些标准的措词,而不仅仅是“您错了”。我已经知道我错了。那就是我问的原因。 😀
const std::string
类型的左值表达式(不是引用!)const std::string
,const std::string
,所以它是从const std::string
const std::string
。最佳答案
在本节中,您引用:
第二和第三操作数都是std::string const
类型的左值,因此结果是std::string const
类型的左值。
但是我们不是从std::string
初始化std::string
。在:
const std::string& foo(const std::string& s1, const std::string& s2)
{
return (s1.size() < s2.size() ? s1 : s2);
}
我们正在从std::string const&
类型的左值初始化std::string const
。那仅仅是直接引用绑定(bind)。无需复制。关于c++ - C++是否不要求这样做(cond?string_1 : string_2) initialize a string?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63198098/