【问题标题】:Bind rvalue reference to (auto generated) lvalue将右值引用绑定到(自动生成的)左值
【发布时间】:2019-03-07 10:32:34
【问题描述】:

我的搜索发现很多关于右值绑定到左值的帖子,但没有类似的东西。如有重复请见谅。

struct StrHolder {
    StrHolder(std::string&& s) : name(s) {}
    void Print() const { std::cout << "My name is " << name << std::endl; }
    std::string name;
};

int main()
{
    StrHolder s{"Tom"};  // (1) - OK, as expected
    s.Print();

    std::string n1 {"Angi"};
    StrHolder p{std::move(n1)};  // (2) - OK, also as expected
    p.Print();

    //StrHolder q{n1}; // (3) - NOT OK. Also expected. Cannot bind rvalue reference to lvalue
    //q.Print();

    auto name1 {"Bon"}; // name1 is an lvalue
    StrHolder z{name1}; // (4) - Why is this OK ?
    z.Print();

    return 0;
}

上面声明为auto的变量'name1'是一个左值。因此,“z”的初始化应该会失败,但它不会。

我在这里遗漏了什么吗?

【问题讨论】:

  • 与手头的问题无关,但注意name要初始化为name(std::move(s)),否则会出现拷贝。
  • @Angew:是的。谢谢指正。

标签: c++ auto rvalue lvalue


【解决方案1】:

name1 是一个左值...但它不是std::string,而是char const*。从它构造一个StrHolder 需要使用来自char const* 的隐式构造函数来创建一个临时的std::string,然后调用StrHolder::StrHolder() 并使用对该临时的右值引用。 name1 被单独留下,永远不会离开。

【讨论】:

  • (感谢 Agnew 在自删除后的答案中指出 name1 具有数组类型,而不是指针类型。)
  • 其实我错了,所以我把答案删了。 auto 遵循与模板参数推导相同的规则,确实执行数组到指针的转换。 "Proof"
  • 哈。然后现在向你提出纠正我的建议。 :-D
  • 感谢大家的快速回答。根据您的输入生成失败的示例: auto name1{n1}; StrHolder z{name1};
猜你喜欢
  • 2017-12-06
  • 1970-01-01
  • 2014-10-31
  • 2017-04-13
  • 2014-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
相关资源
最近更新 更多