右值参数的隐式生成函数重载?

很抱歉,如果之前有人问过这个问题,或者我错过了一些琐碎的事情,但是以下参考资料对我来说并不明确。我了解为什么在函数参数不是引用时允许传递rvalue而不是lvalue的原因,但是我不明白当函数参数是const引用(对我而言没有意义)但被禁止时允许传递rvalue的原因通过常规参考(逻辑行为)时。

假设我有以下代码

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" });
}

现在,我了解了为什么为f隐式地为A &&生成了重载,但是A&和const A&的行为使我感到困惑。

  1. 为什么编译器禁止传递A &&而不是A&,但是允许传递A &&而不是A&?
  2. 这是错误还是功能?
  3. 如果它是一项功能,允许它的原因是什么?

谢谢。

评论
  • 路飞
    路飞 回复
    我不明白当函数参数是const引用时允许[传递右值代替左值]的原因

    这使得从右值复制成为可能。可能还有其他原因,但这是非常重要的功能。