Reputation: 6798
It's time for another 'how do i do this in c++ without loosing my grip'-question!
This time:
Considering the following code taken from cplusplus.com:
template<class InputIterator, class OutputIterator>
OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result )
{
while (first!=last) *result++ = *first++;
return result;
}
Is there a way to cast *first
to the type of *result
?
In other words: is there a way to determine (at compiletime) the type of result?
Upvotes: 2
Views: 292
Reputation: 209
The short answer is no. If OutputIterator is really an OutputIterator (e.g. an ostream_iterator), then: typename std::iterator_traits::value_type will be void, and in C++0x, decltype(*result) is likely to be OutputIterator. (So Armen's suggestion doesn't work in template code.)
And Tony's suggestion involving reinterpret_cast doesn't work either. In fact, it will break things that do work (e.g. when InputIterator is returning int, and OutputIterator wants double).
The only real answer is Oli's. Which is logical: what you really want to do is transform your data, not just copy it.
Upvotes: 1
Reputation: 106196
You can modify the copy routine to use a template to do the casting...
template <typename A, typename B>
const A& cast(const A&, const B& b)
{
return *reinterpret_cast<const A*>(&b);
};
template <class InputIterator, class OutputIterator>
OutputIterator mycopy(InputIterator first, InputIterator last,
OutputIterator result)
{
for ( ; first != last; ++first, ++result)
*result = cast(*result, *first);
return result;
}
That said, Oli's answer's much better if your not specifically looking to learn how to modify copy to handle this....
Upvotes: 1
Reputation: 272647
Not a precise answer to your question, but it sounds like you want don't really want to std::copy
, you want to std::transform
your data to another type. In which case, do something like:
template <typename A, typename B>
B convert(A x) { return static_cast<B>(x); }
...
std::transform(v1.begin(), v1.end(), v2.begin(), convert<float,int>);
Upvotes: 1
Reputation: 133064
yes, the type of *result
is ('cause the type of result
is OutputIterator
)
typename std::iterator_traits<OutputIterator>::value_type
of course, if OutputIterator is a pointer or a correctly written STL-compatible iterator. Otherwise, no, I think there is no way. In the upcoming C++0x, it would be much easier, that is,
decltype(*result)
HTH,
Armen
Upvotes: 6