LINUX.ORG.RU

как изменять данные на лету?


0

0

у меня есть vector<float>, который держит значения углов в радианах. Что-бы распечатать все значения вектора делаю обычно так:

copy (radians.begin(),radians.end(),ostream_iterator<float>(cout," "));

НО... печатать их надо в градусах.
По идее, можно сделать так:
for (vector<float>::const_iterator i=radians.begin();i!=radians.end();++i){
cout<<(*i)*PI/180.0<<' ';
}
Как видите, это очень громоздко и неудобно, поэтому очень хочется добится того-же результата используя copy, вот только не знаю как.
Помогите, пожалуйста.

★★

А кто мешает отнаследоваться от ostream_iterator и производить преобразования в перегруженном операторе? Ведь всего-то один флоат нужно...

Flogger_d
()

Например, так:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <cmath>

class MyIterator : public std::ostream_iterator<float>{
public:
MyIterator(std::ostream& ostr,const char* delim):std::ostream_iterator<float>(ostr,delim){}
MyIterator& operator=(const float& angle){
std::cout << "In grad: ";
std::ostream_iterator<float>::operator=(float(angle*180/M_PI));
return *this;
}
MyIterator&
operator*() { return *this; }

MyIterator&
operator++() { return *this; }

MyIterator&
operator++(int) { return *this; }

};

int main(){
std::vector<float> data;
data.push_back(M_PI);
data.push_back(M_PI/4);
data.push_back(M_PI/3);
data.push_back(M_PI/2);

std::copy(data.begin(),data.end(),MyIterator(std::cout," "));
std::cout << std::endl;
return 0;
}

Flogger_d
()
Ответ на: комментарий от phrm

Ну тебе насоветовали!!!! Не слушай таких, читай Страуструпа.

Смотри сюда для твоего std::vector<float> radians:

void to_gradus(const float &rad)
{
    cout << 180.0 * rad / PI;
}

std::for_each(radians.begin(), radians.end(), to_gradus);

anonymous
()
Ответ на: комментарий от anonymous

зря Вы так выражаетесь.
Ваш вариант не предусматривает иних потоков, кроме cout.
Таким образом, для любого другого потока, нужно клепать функцию и делать поток глобальным. Не удобно.
(можно впихнуть поток и float в один struct и посылать его в функцию, но это как-то не то )

phrm ★★
() автор топика
Ответ на: комментарий от phrm

Ваши слова "Что-бы распечатать все значения вектора... печатать их надо в градусах."? Где в вопросе говорится о произвольном потоке?

Ещё раз отправляю вас к Страуструпу, на предмет алгоритмов, манипуляторов и операций над стандартными контейнерами.

Вот пример операции с произвольным потоком для любого
std::vector<T>:

template <class T>
struct to_gradus
{
    to_gradus(std::basic_stream &stream)
    {
        this->stream = stream;
    }
    operator () (const T &o)
    {
        stream << o;
    }
private:
    std::basic_stream stream;
};

std::vector<float> radians;

for_each(radians.begin(), radians.end(), to_gradus<float>(std::cout));

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

anonymous
()
Ответ на: комментарий от anonymous

Поправочка:

template <class T>
struct to_gradus
{
    to_gradus(std::basic_stream &stream): _stream(stream)
    {
    }
    operator () (const T &o)
    {
        stream << o;
    }
private:
    std::basic_stream &_stream;
};

anonymous
()
Ответ на: комментарий от anonymous

Оправданы оба подхода - просто по той причине, что stream- итераторы существуют. Представьте себе ситуацию, когда нужно не выводить данные в поток, а читать из него и преобразовывать на лету. Алгоритм for_each в данном случае не работает, а перегрузка istream_iterator решает эту проблему.

Flogger_d
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.