質問

From another question I see this code :

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

Can't we just use below code ? :

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

Is there any difference ??

I can't understand the reason for using the first approach.

Is the second code inhibit RVO ?

役に立ちましたか?

解決

The first version takes a std::set by reference which means you will not get a copy of the argument that is passed. The copy is actually happening in the initialization of result with a. The second takes its argument by value, which means that depending on the value-category of the argument the compiler will call the copy/move constructor. Particularly, if the argument is an lvalue, it is copied, and if an rvalue, moved.

In the first example, the compiler will most likely will discard the copy operation from the return statement, an optimization known as return value optimization (RVO). The second version cannot do this as you are not returning a local variable. So you can see that the second version of the function has to incur at least one extra copy or move operation, while the first deals only with one.

他のヒント

In fact these two functions are equivalent. Either a new set is created by copy of the argument that corresponds to parameter a when the function is called

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

or it is created inside the body of the function

template <typename T>
std::set<T> getUnion(const std::set<T>& a, const std::set<T>& b)
{
  std::set<T> result = a;
//...

However it is more clear for readers of the code when the function is defined as in the first case

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

For example the function could be declared as

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

could not it?

These variety only arises questions.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top