开发者

"Double" function with C++0x

开发者 https://www.devze.com 2023-03-30 12:11 出处:网络
Lets say I have the following simple Vector class: template <class N> class Vector<N> { public:

Lets say I have the following simple Vector class:

template <class N>
class Vector<N>
{
public:
  std::array<int, N> a;
};

My first attempt at double is the following:

template <class N>
Vector<N>&& double1(Vector<N>&& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return static_cast<Vector<N>&&>(x);
}

This looks ok initially, but if I do:

auto x&& = double1(makeVector(1,2,3))

I'll have references to temporary issues.

My second attempt is the following:

template <class N>
Vector<N> double2(Vector<N>&& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return x;
}

Which seems not to have the above reference to temporary issue, but does what I think is an unnecessary move/copy on return.

I could avoid both the reference to temporary issues and extra moves/copies by doing the following:

template <class N>
void double3(Vector<N>& x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
}

But then I have to make changes to the argument, which I think is a bit messy. I'll also have to name the temporaries.

My final idea was the following:

template <class N>
Vector<N> double4(Vector<N> x) 
{ 
  for (int i = 0; i != N, ++i) { x.a[i] *= 2; }
  return x;
}

Which would avoid all copies if the parameter was stored in the same place as the result, but I'm not sure how to do this.

Basically I'm looking for a double function that has the following properties:

(1) No references to temporary issues when assigned with auto.

(2) No co开发者_如何转开发pies when passed a temporary.

(3) Doesn't modify argument when passed a non-temporary.

Anyone have any idea how to put these three things together?

Edit

Perhaps to put things more simply, this is the behaviour I want.

(1) If the argument is a temporary, modify it in place.

(2) Otherwise, make a copy.


Your final idea is correct and efficient, go with it:

template <class N>
Vector<N> double4(Vector<N> x) 
{ 
  for (int i = 0; i != N, ++i) { x[i] *= 2; }
  return x;
}


This code does not make sense.

First, std::array takes two template parameters: a type and a size. Second, std::array is an aggregate; it isn't really moveable. The contents can be moved, but not the object itself.

Third, you're abusing r-value references to no apparent gain. If you want to double something, just use a regular reference just like you would have before C++0x.

But then I have to make changes to the argument, which I think is a bit messy. I'll also have to name the temporaries.

There is nothing wrong with having to actually store objects. Not everything needs to be a temporary. You gain absolutely no efficiency by trying to push a temporary though a function call, if for no other reason than that C++ doesn't allow it.

And there's nothing "messy" about changing a parameter; C++ is not a functional language.

Oh, and r-value references are not "references to temporaries." They can reference temporaries, but that's not the only thing they do.

0

精彩评论

暂无评论...
验证码 换一张
取 消