【问题标题】:lvalue and rvalue reference can combine in one?左值和右值引用可以合二为一吗?
【发布时间】:2021-03-24 01:43:15
【问题描述】:

我发现下面的链接说“左值和右值引用接口可以结合在一起”。 Pass lvalue to rvalue

但是当我以它为例时。出现编译错误cannot bind ‘std::string {aka std::basic_string}’ lvalue to ‘std::string&& {aka std::basic_string&&}’。下面是我的实现。

#include <iostream>
#include <string>

using namespace std;

void g(string &&b) {
    cout << b << endl;
}

void g(const string &b) {
    cout << b << endl;
}

void f(string &&a) {
    g(std::forward<string>(a));
}

int main()
{
    f("1122");
    string a("222");
    f(a);
    return 0;
}

我的意思是“void f(string &&a)”和“void f(const string &a)”可以合二为一。然后我们只需要调用“void f(string &&a)”,它既可以接收右值引用也可以通过前导接收左值。

--------- 添加说明

这可能是电话universal reference

【问题讨论】:

  • 您想要关注链接问题的哪个答案?是使用模板(与您的代码不同)还是直接执行统一函数(您的代码统一函数)?两者都不是您所做的完美匹配,并且您链接到问题而不是特定答案...

标签: c++


【解决方案1】:

要将右值引用和左值引用合并为一个引用,您需要使用所谓的通用引用。这些在 C++ 中通过 auto &amp;&amp; 或带有 && 引用的模板定义。参见例如 What is move semantics? ,不过,非常特别的是,我想您会在 stackoverflow 之外找到更多平易近人的解释。搜索“通用参考 C++”。

现在,回到您的代码。你只需要这个:

template <typename T>
void f(T &&a) 
{
    g(std::forward<string>(a));
}

就是这样。通过模板加上 && 引用定义的通用引用。请注意,我必须将 string 替换为 T

然而,简单是我们最好的朋友。如果您不需要模板,为什么不使用旧的、好的 const 参考?

void f(const string & a) 
{
  g(a);
}

对我来说,这是最好的解决方案。

【讨论】:

  • 谢谢你明确回答!但我有一个队列类已经使用A universal reference defined via a template plus a &amp;&amp;-reference,但它可以成功传递右值但不能传递左值。可能是什么问题?它是一个带模板的类成员函数。
  • @dahohu527,我猜:你有一个类模板template&lt;class T&gt; class my_class { ... }; 和一个成员函数void foo(T&amp;&amp;)。在这种情况下T&amp;&amp; 不是一个通用引用,而只是一个右值引用,并且右值引用不能绑定到左值。如果你有template&lt;class S&gt; foo(S&amp;&amp;)S&amp;&amp; 将是一个通用参考。
  • @Evg 是的,你是对的,这真的很难理解。这篇文章很有帮助。 isocpp.org/blog/2012/11/…
猜你喜欢
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
相关资源
最近更新 更多