2010-05-10 59 views
3
template< class T1, class T2 > 
class Pair { 
    T1 first; 
    T2 second; 
}; 

我被要求寫一個交換()方法,使得第一元件成爲第二和第二第一。我有:C++:交換不同類型的模板類元素?

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

但這返回一個新的對象,而不是交換,在那裏我覺得它需要改變自己的數據成員一個void方法。這是可能的,因爲T1和T2可能是不同的類類型?換句話說,我不能簡單地設置temp = first,first = second,second = temp,因爲它會嘗試將它們轉換爲不同的類型。我不知道爲什麼你可能想要有一個模板對象改變其類型的順序,因爲它似乎會造成混亂,但似乎是我被要求做的事情。

編輯:謝謝大家回答!和我想的一樣,交換位置顯然沒有任何意義,對swap()函數的請求非常模糊。

+1

我會選擇與swap不同的名稱。過去人們使用標準庫的人會認爲'swap'是爲了交換同一類型的兩個對象的內容。 「翻轉」怎麼樣? – 2010-05-10 19:04:36

+0

@Emile:我不認爲這是一個大問題。它是一個'swap()',它需要__one參數___由__two部分組成.__它可以做什麼,但交換這些?然而,不尋常的是,它不可能(不過,我不知道怎麼做)一個就地交換。這確實不同於我們所知道的swap()。 – sbi 2010-05-11 05:30:30

回答

7

你不能換就地,因爲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模板的成員。)

你可以,但是,添加超載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! 
+2

從現場交換到基於過載的場外交換似乎是一個真正的潛在混亂源。 – 2010-05-10 19:27:32

+0

@丹尼斯:我不確定你想告訴我什麼。 ':-x' – sbi 2010-05-10 21:44:32

+0

你建議爲'T1'和'T2'是同一類型提供一個重載。但是,這種重載提供了與原始形式完全不同的語義。 'a = swap(b)'可能會也可能不會修改'b',具體取決於類型。這不是我所期望的。 – 2010-05-10 22:19:51

2

只有T1可以被轉換成T2,反之亦然才能進行轉換。如果可能的話,那麼你可以寫

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

(請注意,您無法從Pair<T1,T2>改變*thisPair<T2,T1>這個void功能。)

1

由於pair <T1,T2>pair <T2,T1>是你不能用它來交換不同類型。當沒有給出內置交換操作時(例如,在std::vector有一個交換操作),交換本身也不會比使用臨時變量更多。 Howeyer你可以使用引用創建一個新類型。或者你使用指針,其中複製便宜。

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