"Double" function with C++0x
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.
精彩评论