更多 C++ 慣用法/Boost 變種
外觀
當所有成員都是相同型別時,重新排序 普通舊資料 (POD) 型別的成員,而無需實際重新組織或複製資料項。
使用 Boost 的 Bimap 最好地說明了這種慣用法。 [1] Boost.Bimap 是一個用於 C++ 的雙向對映庫。在 bimap<X,Y> 中,型別 X 和 Y 的值都可以用作鍵。可以使用 Boost 變種慣用法最佳化這種資料結構的實現。
Boost 變種慣用法利用 reinterpret_cast,並且很大程度上依賴於這樣的假設:具有相同資料成員(型別和順序)的兩個不同結構的記憶體佈局是可互換的。雖然 C++ 標準沒有保證此屬性,但實際上所有編譯器都滿足此屬性。此外,如果只使用 POD 型別,則變種慣用法是標準的。 [2] 以下示例顯示了 Boost 變種慣用法的工作原理。
template <class Pair>
struct Reverse
{
typedef typename Pair::first_type second_type;
typedef typename Pair::second_type first_type;
second_type second;
first_type first;
};
template <class Pair>
Reverse<Pair> & mutate(Pair & p)
{
return reinterpret_cast<Reverse<Pair> &>(p);
}
int main(void)
{
std::pair<double, int> p(1.34, 5);
std::cout << "p.first = " << p.first
<< ", p.second = " << p.second << std::endl
<< "mutate(p).first = " << mutate(p).first
<< ", mutate(p).second = " << mutate(p).second << std::endl;
}
給定一個僅包含 POD 資料成員的 std::pair<X,Y> 物件,Reverse<std::pair<X,Y>> 的佈局與大多數編譯器上的 pair 的佈局相同。Reverse 模板在不實際反轉資料的情況下反轉資料成員的名稱。一個輔助 mutate 函式用於輕鬆構造一個 Reverse<Pair> 引用,它可以被視為原始 pair 物件的檢視。上述程式的輸出證實了可以在不重新組織資料的情況下獲得反向檢視。
p.first = 1.34, p.second = 5 mutate(p).first = 5, mutate(p).second = 1.34
- ↑ Capeletto, Matias. "Boost.Bimap".
- ↑ http://beta.boost.org/doc/libs/1_43_0/libs/bimap/test/test_mutant.cpp