从迭代器获取const_iterator

时间:2011-07-05 16:20:18

标签: c++ templates stl iterator template-meta-programming

  

可能重复:
  Obtaining const_iterator from iterator

我想编写一个元函数,从const_iterator

返回相应的iterator
template <class Iterator>
struct get_const_iterator
{
    typedef ??? type;
};
  • get_const_iterator<int*>::type必须为const int*
  • get_const_iterator<const int*>::type必须为const int*
  • get_const_iterator<int* const>::type必须是const int*const int* const,我不在乎
  • get_const_iterator<std::list<char>::iterator>::type必须为std::list<char>::const_iterator

可以使用iterator_traits还是不使用它们?

编辑: 我们假设如果2个容器具有相同的iterator类型,那么它们也具有相同的const_iterator类型。我认为这是一个合理的假设,虽然理论上并不完全正确。

2 个答案:

答案 0 :(得分:1)

你可以在C ++ 0x

中完成
template <typename Container>
Container container (typename Container :: iterator);

template <typemame Iterator>
struct get_const_iterator
{
    typedef decltype (container (Iterator())) :: const_iterator type;
};

虽然我开始同意Steve的观点 - 这不是一般解决方案,因为不同的容器可能具有相同的迭代器类型。

答案 1 :(得分:1)

如果您愿意对容器进行部分专业化,可以在当前标准中执行此操作,如...

#include <vector>
#include <list>
#include <iterator>

// default case
template <typename Iterator, typename value_type, typename container_test = Iterator>
struct container
{
  typedef Iterator result;
};

// partial specialization for vector
template <typename Iterator, typename value_type>
struct container<Iterator, value_type, typename std::vector<value_type>::iterator>
{
  typedef typename std::vector<value_type>::const_iterator result;
};

// partial specialization for list, uncomment to see the code below generate a compile error
/* template <typename Iterator, typename value_type>
struct container<Iterator, value_type, typename std::list<value_type>::iterator>
{
  typedef typename std::list<value_type>::const_iterator result;
}; */

// etc.

template <typename Iterator>
struct get_const
{
  typedef typename container<Iterator, typename std::iterator_traits<Iterator>::value_type>::result type;
};

int main(void)
{
  std::list<int> b;
  b.push_back(1);
  b.push_back(2);
  b.push_back(3);
  get_const<std::list<int>::iterator>::type it1 = b.begin(), end1 = b.end();
  for(; it1 != end1; ++it1)
    ++*it1; // this will be okay

  std::vector<int> f;
  f.push_back(1);
  f.push_back(2);
  f.push_back(3);

  get_const<std::vector<int>::iterator>::type it = f.begin(), end = f.end();
  for(; it != end; ++it)
    ++*it; // this will cause compile error

}

当然,将重复史蒂夫的观点,并且要求是你的迭代器存在iterator_traits