Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to get the value type from an arbitrary iterator (C++)?

Tags:

c++

templates

I have a class

template <typename Iterator, typename Value>
class Foo {
 public:
  Foo(const Iterator& it) { ... }
  ...
 private:
   map<Value, int> m_;
  }
};

Is there any way to get rid of Value in the template? The Iterator may or may not be an STL iterator, but it's guaranteed that *it type is Value.

I know about iterator_traits<T>::value_type for STL iterators, but wonder if there's any way to get Value type automatically for an arbitrary Iterator type?

One trick I'm thinking about - say, we have a helper class

template <typename Iterator, typename Value>
class Bar {
 public:
  Bar(const Iterator& dummy_iterator, const Value& dummmy_value) {}
  ...
};

Then if we instantiate Bar as Bar(it, *it), the type of Value will be known inside Bar. But I can't find a good way to combine Bar with Foo.

like image 890
Igor Krivokon Avatar asked Jul 10 '09 00:07

Igor Krivokon


People also ask

What is the datatype of iterator?

There are various kinds of iterators: input, output, forward, bidirectional, and random-access. Each has a different specification, and although random-access is a strict superset of the bidirectional interface, they are totally unrelated in the C++ type system.

How do iterators work in C?

An iterator is an object that allows you to step through the contents of another object, by providing convenient operations for getting the first element, testing when you are done, and getting the next element if you are not. In C, we try to design iterators to have operations that fit well in the top of a for loop.

What is an iterator What are types of iterators?

An iterator is an object that can iterate over elements in a C++ Standard Library container and provide access to individual elements.


Video Answer


2 Answers

Any iterator should provide iterator_traits<Iterator>::value_type. If it does not, then it is not an iterator. ISO C++ 2003 24.3.1[lib.iterator.traits] "Iterator traits":

To implement algorithms only in terms of iterators, it is often necessary to determine the value and difference types that correspond to a particular iterator type. Accordingly, it is required that if Iterator is the type of an iterator, the types

iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::iterator_category

be defined as the iterator’s difference type, value type and iterator category, respectively.

Aside from that, there's no general way to obtain a type of an arbitrary C++ expression. C++0x will rectify it by providing decltype.

like image 156
Pavel Minaev Avatar answered Oct 22 '22 16:10

Pavel Minaev


Sorry. The correct way to get rid of Value is to use iterator_traits as you suggested.

If your non-STL iterator is a naked pointer, then you get correct iterator_traits typedefs for free. Otherwise the non-STL iterator class must define the correct typedefs.

See the iterator traits documentation for more information.

like image 43
Jon-Eric Avatar answered Oct 22 '22 14:10

Jon-Eric