1

我想在容器上有一个模板和两种元组类型,这样我就可以将以下两个函数合并为一个:

template<typename Container>
void vblock(int row, int col, const Container& container) {
  foreach( const typename Container::value_type& item, container ) {
    cell(row, col, item);
    ++row;
  }
}

template<typename container, typename T1, typename T2>
void vblock(int row, int col,
          const std::list<typename boost::tuple<T1, T2> >& container) {
  typedef boost::tuple<T1, T2> Tuple;
  foreach( const Tuple& item, container ) {
    cell(row, col, item.template get<0>());
    cell(row + 1, col, item.template get<1>());
    ++col;
  }
}

template<typename container, typename T1, typename T2>
void vblock(int row, int col,
          const std::set<typename boost::tuple<T1, T2> >& container) {
  typedef boost::tuple<T1, T2> Tuple;
  foreach( const Tuple& item, container ) {
    cell(row, col, item.template get<0>());
    cell(row + 1, col, item.template get<1>());
    ++col;
  }
}

我已经检查了C++ 模板 - 指定容器类型和它所拥有的容器元素类型以及使用 STL 容器和 typedef 的 C++ 模板类,但它们没有回答我的问题。

适合 STL 容器的简单 C++ 模板问题与我的问题最相似,但我不知道如何为 boost::tuple 添加模板。谢谢!

4

2 回答 2

1

把事情简单化:

template <typename C>
void vblock(int row, int col, C const & container)
{
    typedef typename C::value_type tuple_type;
    typedef typename boost::element<0, tuple_type>::type first_type;
    typedef typename boost::element<1, tuple_type>::type second_type;

    // ...
}

您可以在函数声明中添加一些enable_if逻辑,以防止创建不可能的重载,但也许现在还不需要。

于 2012-08-15T13:39:23.983 回答
0

Kerrek SB 的解决方案很好,适用于一般情况(我投了赞成票)。

最后,我选择了一个稍微不同的实现,它使用函数重载,这是一种可能的替代方案,特别是因为它不需要 enable_if 并且仍然很优雅:

template<typename Container>
void vblock(int row, int col, const Container& container) {
  foreach( const typename Container::value_type& item, container ) {
    vblock_cell_impl(row, col, item);
    ++row;
  }
}

template<typename T>
void vblock_cell_impl(int row, int col, const T& item) {
  cell(row, col, item);
}

template<typename T1, typename T2>
void hblock_cell_impl(int row, int col, const boost::tuple<T1, T2>& item) {
  cell(row, col, item.template get<0>());
  cell(row + 1, col, item.template get<1>());
}
于 2012-08-16T06:13:18.343 回答