开发者

Converting arrays in stl like copy

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 deter开发者_开发问答mine (at compiletime) the type of result?


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


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>);


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....


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜