Reputation: 10275
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.
Upvotes: 14
Views: 3881
Reputation: 5339
As to getting value type of iterator previous answers were correct.
But there is more. The trick you are thinking of would not work with class. If Bar
was a function like:
template <typename Iterator, typename Value>
void bar(const Iterator& dummy_iterator, const Value& dummmy_value) {}
then type deduction would work for bar(it, *it)
and you would have the value type inside of bar
. (But keep in mind that to use this trick you would still have to have a dereferencable iterator it which is not always good - how to deal with empty sequence then?)
Using a class Bar
you would have to provide the template arguments Iterator
and Value
manually as there is no type deduction for classes and using Bar(it, *it)
would no compile.
Upvotes: 1
Reputation: 101585
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 typesiterator_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
.
Upvotes: 18
Reputation: 17275
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.
Upvotes: 1