我应该发送std::set函数与参考或不

Should I send std::set to function with refrence or not?

本文关键字:参考 函数 set std 我应该      更新时间:2023-10-16

从另一个问题中我看到了以下代码:

template <typename T>
std::set<T> getUnion(const std::set<T>& a, const std::set<T>& b)
{
  std::set<T> result = a;
  result.insert(b.begin(), b.end());
  return result;
}

我们就不能用下面的代码吗?:

template <typename T>
std::set<T> getUnion(std::set<T> a, const std::set<T>& b)
{
  a.insert(b.begin(), b.end());
  return a;
}

有什么区别吗??

我不明白为什么用第一种方法。

第二个代码是否抑制RVO ?

第一个版本通过引用获取std::set,这意味着您将不会获得传递的参数的副本。复制实际上发生在resulta的初始化过程中。第二个方法按值接受实参,这意味着编译器将根据实参的值类别调用复制/移动构造函数。特别是,如果参数是左值,则复制它,如果是右值,则移动它。

在第一个例子中,编译器很可能会放弃返回语句中的复制操作,这种优化称为返回值优化(RVO)。第二个版本不能这样做,因为您没有返回一个局部变量。因此,您可以看到,函数的第二个版本必须引起至少一个额外的复制或移动操作,而第一个版本只处理一个操作。

实际上这两个函数是等价的。在调用函数

时,通过复制对应于形参a的实参创建一个新的集合。
template <typename T>
std::set<T> getUnion(std::set<T> a, const std::set<T>& b)
{
//...

或者在

函数体中创建
template <typename T>
std::set<T> getUnion(const std::set<T>& a, const std::set<T>& b)
{
  std::set<T> result = a;
//...

然而,当函数定义为在第一种情况下

时,对于代码的读者来说更清楚
template <typename T>
std::set<T> getUnion(const std::set<T>& a, const std::set<T>& b);

例如,函数可以声明为

template <typename T>
std::set<T> getUnion( const std::set<T> &a, std::set<T> b);

可以吗?

这些变化只会引起问题。