3
template< class T1, class T2 >
class Pair {
    T1 first;
    T2 second;
};

我被要求编写一个 swap() 方法,以便第一个元素成为第二个元素,第二个元素成为第一个元素。我有:

Pair<T2,T1> swap() {
    return Pair<T2,T1>(second, first);
}

但这会返回一个新对象而不是交换,我认为它需要是一个更改自己的数据成员的 void 方法。由于 T1 和 T2 可能是不同的类类型,这可能吗?换句话说,我不能简单地设置 temp=first, first=second, second=temp 因为它会尝试将它们转换为不同的类型。我不确定为什么您可能希望拥有一个更改其类型顺序的模板对象,因为这似乎会引起混淆,但这似乎是我被要求做的事情。

编辑:谢谢大家的回答!和我想的差不多,就地交换显然没有任何意义,swap() 函数的请求非常模棱两可。

4

3 回答 3

8

您不能就地交换,因为T1T2不必是同一类型。Pair<T1,T2>是与 不同的类型Pair<T2,T1>。您必须返回一个与原始对象不同类型的对象,因此它必须是一个新对象。

我要做的是:

template< class T1, class T2 >
Pair<T2,T1> swap(const Pair<T1,T2>& pair) {
    return Pair<T2,T1>(pair.second, pair.first);
}

(没有理由让它成为您的Pair模板的成员。)

但是,您可以为 when和are 相同类型添加重载:T1T2

template< class T >
Pair<T,T>& swap(Pair<T,T>& pair) {
    using std::swap;
    swap(pair.first, pair.second);
    return pair;
}

但是,正如丹尼斯在评论中提到的那样,这可能确实非常令人困惑。

另一个想法是为您的模板定义一个转换构造函数Pair,以便可以交换隐式可转换类型:

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

然后你可以像这样交换:

Pair<int,double> p1(42,47.11);
Pair<double,int> p2(p1.second,p1.first);

但请注意,这也支持其他可能不需要的隐式转换:

Pair<char,float> p3(p1.second, p1.first); // narrowing! 
于 2010-05-10T18:44:12.213 回答
2

只有当 T1 可以转换为 T2 时,交换才是可能的,反之亦然。如果可能的话,你可以写

T2 temp (first);
first = T1(second);
second = temp;

(请注意,您不能使用此功能将 a 更改*thisPair<T1,T2>a 。)Pair<T2,T1>void

于 2010-05-10T18:44:52.180 回答
1

作为不同的类型pair <T1,T2>pair <T2,T1>您不能在其上使用交换。std::vector当没有给出内置交换操作时(例如 at有一个),交换本身也没有做更多的事情。但是,您可以使用引用创建新类型。或者你使用指针,复制很便宜。

    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);
于 2010-05-10T18:51:03.670 回答