【发布时间】:2020-05-18 04:17:52
【问题描述】:
如果之前有人问过这个问题,或者我遗漏了一些琐碎的事情,我很抱歉,但是以下参考资料对我来说并不清楚。我理解为什么在函数参数不是引用时允许传递右值而不是左值,但是我不明白当函数参数是 const 引用时允许传递右值而不是左值的原因(这对我来说没有意义)但被禁止传递通常的引用时(逻辑行为)。
假设我有以下代码
struct A
{
explicit A(std::string s) : name{ s } { };
A(const A& a) : name{ a.name } { }
A& operator=(const A& a) { name = a.name; return *this; }
A(A&& a) noexcept : name{} { std::swap(name, a.name); }
A& operator= (A&& a) noexcept { std::swap(name, a.name); return *this; }
void talk() const{ std::cout << name << " says blablabla.\n"; }
private:
std::string name;
};
void f(A a) {}
void g(A& a) {}
void h(const A& a) {}
int main()
{
A a{ "a" };
f(a);
f(A{ "temp" });
g(a);
g(A{ "temp" }); // Compile error
h(a);
h(A{ "temp" });
}
现在,我明白了为什么 A&& 为 f 隐式生成重载,但是 A& 和 const A& 的行为让我感到困惑。
- 为什么编译器禁止传递 A&& 而不是 A& 而允许传递 A&& 而不是 A&?
- 这是错误还是功能?
- 如果它是一项功能,那么允许它的原因是什么?
谢谢。
编辑: 建议的问题不完全是我问的。我的问题是,为什么它允许绑定临时对象,即使它是 const。链接的问题询问“为什么它不是 const 时禁止”。
已接受的答案:eerorika 在 cmets 中对他的问题提供的答案最有意义,这是与 pre c++11 的向后兼容性。
【问题讨论】:
-
请注意,该行正在尝试将临时绑定到非常量引用。
-
我不确定。我的问题是为什么“它允许绑定”问题是“为什么禁止”。
-
所以你对
h()不是g()感到困惑? -
你可以这样说。我很好奇,为什么允许隐式绑定到临时值,无论它是否是 const 。两者都有潜在的危险。当然,您可以争辩说,除了读取它的值(例如,如果我使用 const 引用并在 setter 函数中获取它的地址)之外,在函数内部使用 const 引用做一些事情是一个坏主意,无论如何都应该不鼓励,但仍然如此。 .. 如果你确实允许这个绑定,为什么只在 const 引用的情况下才允许它。
标签: c++ overloading pass-by-reference