更多 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