【问题标题】:How to pass an rvalue as a reference argument to a function如何将右值作为引用参数传递给函数
【发布时间】:2018-09-09 22:03:24
【问题描述】:

我有一个获取对象引用的函数。在一个特定的调用实例中,我不关心函数如何处理该特定对象。因此,我希望我可以避免在主函数中创建该对象。

代码如下:

#include <stdio.h>
#include <unordered_map>

void myFunc(std::unordered_map<int,int> &mp);

int main() {
  myFunc(std::unordered_map<int,int>());
  return 0;
}

void myFunc(std::unordered_map<int,int> &mp) {
  printf("%d\n",mp.size());
  printf("Hello world.\n");
}

底线是:我不想在主函数中声明和初始化unordered_map&lt;int,int&gt; 对象。此版本代码报告:

错误:从“std::unordered_map”类型的右值初始化“std::unordered_map&”类型的非常量引用无效

我也试过const_cast&lt;&gt;std::move,但都不起作用。

如果我们将 API 更改为:

void myFunc(std::unordered_map<int,int> &&mp)

问题在于 API 在多个文件之间共享,我们真的不想更改它。鉴于 myFunc 的 API 必须修复,我该如何修改 main() 以便我不需要显式创建对象?

--------------编辑-------------------- ----

另一种解决方法是编写一个包装函数:

#include <stdio.h>
#include <unordered_map>

void myFunc(std::unordered_map<int,int> &mp);
void UglyWorkAround(std::unordered_map<int,int> &&mp);

int main() {
  UglyWorkAround(std::unordered_map<int,int>());
  return 0;
}

void UglyWorkAround(std::unordered_map<int,int> &&mp) {
  myFunc(mp);
}

void myFunc(std::unordered_map<int,int> &mp) {
  printf("%d\n",mp.size());
  printf("Hello world.\n");
}

【问题讨论】:

  • 问问自己为什么需要在该函数中使用非常量引用。
  • 那就问问自己,如果对象快要过期了,还做那些操作还有意义吗……
  • 您可以传递&amp;&amp;const&amp;,具体取决于您的目的。您不能(即使可以)也不应该将非常量引用传递给临时对象。
  • @MikeVine 不清楚你在说什么。 C++ 不允许将非 const 左值引用绑定到右值。
  • @juanchopanza 在其他调用实例中,可能需要修改对象。但在这种情况下,我不在乎它是否被修改。

标签: c++ c++11 parameter-passing pass-by-reference rvalue


【解决方案1】:

您避免为std::unordered_map&lt;int, int&gt; 对象编写定义的愿望似乎并非基于任何合理的考虑。但是,既然这是你问的,这里有一种方法:

using M = std::unordered_map<int, int>;
myFunc(const_cast<M&>(static_cast<const M&>(M())));

【讨论】:

  • @RyanHaining 在您链接的问题中讨论的情况下,是的。在类类型的情况下,没有。
  • 看了一圈后,我认为你是对的
【解决方案2】:

如 cmets 中所述,C++ 不允许您为非常量左值引用传入临时值。您提出的带有右值引用的解决方案会破坏您的其他用途。

我对这种情况的建议(根据您的实际使用情况可能不起作用)是添加一个myFunc 重载:

void myFunc() {
  std::unordered_map<int,int> m{};
  myFunc(m);
}

然后将你的 main 改为调用

int main() {
  myFunc();
}

【讨论】:

    猜你喜欢
    • 2020-11-27
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多