跳转到内容

更多 C++ 惯用法/Boost 变种

来自维基教科书,开放的书籍,开放的世界

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

已知用途

[编辑 | 编辑源代码]
[编辑 | 编辑源代码]

参考资料

[编辑 | 编辑源代码]
  1. Capeletto, Matias. "Boost.Bimap".
  2. http://beta.boost.org/doc/libs/1_43_0/libs/bimap/test/test_mutant.cpp
华夏公益教科书