Конвертирование массивов в stl как копии - PullRequest
2 голосов
/ 08 октября 2010

Пришло время для другого вопроса «как мне сделать это в c ++, не теряя своего сцепления» - вопрос!

На этот раз:

Учитывая следующий код, взятый из cplusplus.com :

template<class InputIterator, class OutputIterator>
  OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result )
{
  while (first!=last) *result++ = *first++;
  return result;
}

Есть ли способ привести *first к типу *result?

Другими словами: есть ли способ определить (во время компиляции) тип результата?

Ответы [ 4 ]

6 голосов
/ 08 октября 2010

да, тип *result равен (потому что тип result равен OutputIterator)

typename std::iterator_traits<OutputIterator>::value_type

, конечно, если OutputIterator является указателем или правильно написанным STL-совместимымитератор.В противном случае нет, я думаю, что нет никакого способа.В грядущем C ++ 0x это будет намного проще, то есть

decltype(*result)

HTH,

Армен

1 голос
/ 08 октября 2010

Короткий ответ - нет. Если OutputIterator действительно OutputIterator (например, ostream_iterator), затем: имя типа std :: iterator_traits :: value_type будет недействительным, а в C ++ 0x, decltype (* результат) скорее всего, будет OutputIterator. (Так что предложение Армена не работа в шаблоне кода.)

И предложение Тони с reinterpret_cast не работает или. На самом деле, это сломает то, что работает (например, когда InputIterator возвращает int, а OutputIterator хочет двойной).

Единственный реальный ответ - Оли. Что логично: что ты на самом деле хочу преобразовать ваши данные, а не просто скопировать их.

1 голос
/ 08 октября 2010

Вы можете изменить процедуру копирования, чтобы использовать шаблон для приведения ...

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

Тем не менее, ответ Оли намного лучше, если вы не хотите специально изучать, как изменить копию, чтобы справиться с этим.....

1 голос
/ 08 октября 2010

Не точный ответ на ваш вопрос, но, похоже, вы действительно не хотите std::copy, вы хотите std::transform ваших данных другого типа. В этом случае сделайте что-то вроде:

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