2009-07-17 74 views
2

所以,我有一個宏。是否可以使用宏來專門化std :: swap?

// swap_specialize.hpp 
#include <algorithm> 

#ifndef STD_SWAP_SPECIALIZE 
#define STD_SWAP_SPECIALIZE(CLASSNAME)   \ 
    namespace std {         \ 
    template<> inline        \ 
    void swap(CLASSNAME & lhs, CLASSNAME & rhs) \ 
    { lhs.swap(rhs); } } 
#endif 

所以後來我有一個類

// c.hpp 
#include <vector> 
#include "swap_specialize.hpp" 
class C 
{ 
    public: 
     C(); 

     void swap(C& rhs) 
     { 
      data_.swap(rhs.data_); 
     } 
     C& operator=(C rhs) 
     { 
      rhs.swap(*this); 
      return *this; 
     } 
    private: 
     std::vector<int> data_; 
} 

STD_SWAP_SPECIALIZE(C) 

它是壞的,風格上,要做到這一點?它是一種代碼味道嗎?或者這是一個好習慣?

+2

我不知道我明白。只是手動調用`c.swap(d);`?有什麼問題? – GManNickG 2009-07-17 23:47:49

+0

我同意...有沒有真正的理由想要調用「swap(c,d)」而不是「c.swap(d)」?是不是你認爲前者「看起來更好」?宏通常是一個糟糕的主意,如果可能的話,你應該避免它們......接下來你會知道你會寫下「#define BEGIN {」和「#define END}」,並且從那裏開始都是下坡。 – davr 2009-07-18 00:56:58

回答

6

如果增加可讀性,我會說這沒關係。自我評判。只是我的兩分錢:專精std::swap並不是真正做到這一點的正確方法。考慮這種情況:

my_stuff::C c, b; 
// ... 
swap(c, b); 
// ... 

這將不std::swap如果您還沒有完成using std::swap或類似的東西。你還是申報C的命名自己的交換:

void swap(C &a, C &b) { 
    a.swap(b); 
} 

現在,這也將工作在上述情況下,因爲在類的命名空間參數依賴查找搜索。其中類型是不知道代碼交換通用事情應該去做這樣的:

using std::swap; 
swap(a, b); 

不分類型,這將用最好的匹配互換,和回落到std::swap,如果沒有更好的匹配a的命名空間中的一個。對std::swap的調用進行硬編碼將會減少對不特殊化的類型的類型,但決定在其名稱空間中提供自己的交換。

這是另一種方式:想象一下C是一個模板。在這種情況下,你不能專注於std::swap。但只是定義你自己的交換,那很好。

template<typename T> 
void swap(C<T> &a, C<T> &b) { 
    a.swap(b); 
} 

這就是std::string和其他類的交換如何實現的方式。

0

我沒有看到它買你很多。對於非模板類,它可以節省很少的幾行。而對於模板類,當你想要專門化(即所有的T)時,它就無法工作。

0

假設您正在爲其他許多類使用STD_SWAP_SPECIALIZE(),我認爲這是非常合理的。畢竟它有更多的可讀性,可以有一系列的

STD_SWAP_SPECIALIZE(Foo) 
STD_SWAP_SPECIALIZE(Bar) 
STD_SWAP_SPECIALIZE(Baz) 

比equivilent擴展的代碼。另外,如果STD_SWAP_SPECIALIZE的擴展稍微大一些,那麼如果宏定義需要更改,宏定義會在一個位置給出代碼。 (因爲它是你的例子中的模板定義非常小,所以它可能是一個爭議點)。

相關問題