从迭代器获取const_iterator

13

可能重复:
从迭代器中获取const_iterator

我想编写一个元函数,它可以从一个iterator返回对应的const_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完成吗?还是不需要它们?

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


2
我认为你所要求的对应关系并没有明确定义。原则上,虽然这可能是一种奇怪的实现方式,vector<int>::iteratorlist<int>::iterator可以是同一个类(这对于未能满足单一职责原则来说如何?),但vector<int>::const_iteratorlist<int>::const_iterator可以是不同的类。 - Steve Jessop
@Fred:嗯...可能的重复问题是问是否有一个,而不是如何编写一个 :) - Armen Tsirunyan
@Armen: 通过使用一个驱动底层迭代器并将对元素的所有引用都转为常量的包装器,而不是告诉您任何特定容器作为其const_iterator所使用的实际类型,能解决实际问题吗?事实上,你可能需要多个包装器,因为你希望根据迭代器标签进行调度。 - Steve Jessop
2个回答

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 的观点——这不是一个通用解决方案,因为不同的容器可能具有相同的迭代器类型。


我认为Steve的评论在这里很恰当。 - Lightness Races in Orbit
1
@Armen:把人送进太空曾经是科幻小说,直到他们尝试过……然后一枚火箭因为有人犯了编程错误而爆炸。 - Lightness Races in Orbit
2
此外,这仅满足了@Armen的最后一个需求。 - R. Martinho Fernandes
1
看起来很合理,但我认为不需要我的科幻情节出错。如果多个容器共享一个迭代器,那么即使这些容器实际上都使用相同的const_iterator,对container的调用也是模棱两可的,对吗?实际上,多个容器共享迭代器并不是那么不可思议——例如,如果vector<int>array<int>都使用int*(或者相同的辅助类),那么它们就会共享一个迭代器。不太可能的是,它们随后不会共享一个const_iterator - Steve Jessop
2
@Martinho:公平地说,尝试的部分是棘手的部分。从以往的问题来看,我认为阿尔门可能会为指针类型部分专门化他的结构体 :-) - Steve Jessop
显示剩余5条评论

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

}

当然,会重申Steve上面的观点,并且要求是您的迭代器存在iterator_traits

需要为每种容器类型进行专门处理,因此对于用户容器将无法正常工作。 - Predelnik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接