template< class T1, class T2 >
class Pair {
T1 first;
T2 second;
};
I'm being asked to write a swap() method so that the first element becomes the second and the second the fir开发者_JS百科st. I have:
Pair<T2,T1> swap() {
return Pair<T2,T1>(second, first);
}
But this returns a new object rather than swapping, where I think it needs to be a void method that changes its own data members. Is this possible to do since T1 and T2 are potentially different class types? In other words I can't simply set temp=first, first=second, second=temp because it would try to convert them to different types. I'm not sure why you would potentially want to have a template object that changes order of its types as it seems that would cause confusion but that appears to be what I'm being asked to do.
Edit: Thank you all for answering! Pretty much as I thought, swapping in place obviously does not make any sense, the request for the swap() function was quite ambiguous.
You cannot swap in-place, since T1
and T2
need not be of the same type. Pair<T1,T2>
is a different type than Pair<T2,T1>
. You have to return an object of a different type than the original one, so that has to be a new object.
What I'd do is this:
template< class T1, class T2 >
Pair<T2,T1> swap(const Pair<T1,T2>& pair) {
return Pair<T2,T1>(pair.second, pair.first);
}
(There's no reason to make this a member of your Pair
template.)
You could, however, add an overload for when T1
and T2
are of the same type:
template< class T >
Pair<T,T>& swap(Pair<T,T>& pair) {
using std::swap;
swap(pair.first, pair.second);
return pair;
}
But this, as Dennis mentioned in his comment, might be indeed very confusing.
Another idea is to define a converting constructor for your Pair
template, so that implicitly convertible types can be swapped:
template< class T1, class T2 >
class Pair {
T1 first;
T2 second;
template< class A1, class A2 >
Pair(const A1& a1, const A2& a2) : first(a1), second (a2) {}
};
Then you can swap like this:
Pair<int,double> p1(42,47.11);
Pair<double,int> p2(p1.second,p1.first);
But note that this also supports other, probably unwanted implicit conversions:
Pair<char,float> p3(p1.second, p1.first); // narrowing!
Swapping is possible only if T1 can be casted into T2 and vice-versa. If it's possible then you could write
T2 temp (first);
first = T1(second);
second = temp;
(Note that you cannot change *this
from a Pair<T1,T2>
into a Pair<T2,T1>
with this void
function.)
As pair <T1,T2>
and pair <T2,T1>
are different types you cannot use swap on it. Swap itself also doesn't do much more than using a temporary variable when a build-in swap operation is not given (e.g. at std::vector
has one). Howeyer you can create a new type using references. Or you use pointers, where copying is cheap.
std::pair<int, float> a = std::pair <int, float> (3,3.5);
std::pair<const float &, const int&> b = std::pair<const float &, const int&> (a.first, a.second);
精彩评论