Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как создать манипулятор и перегрузить оператор, который получает этот манипулятор? 
V
    Опции темы
neosapient
Дата 28.8.2014, 10:59 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Здравствуйте.

Допустим есть класс summator. Он получает параметры через перегруженный оператор <<, а затем суммирует их.
Хочу сделать манипулятор calc, который бы производил расчет в момент его вызова. Помогите исправить ошибку.
Пример, что хотелось бы получить
   sum << 1 << 2 << "3" << calc;

Пример не рабочего кода
Код

#include <list>
#include <iostream>
#include <sstream>


class summator{
    std::list<int> vars;

public:
    summator& operator << (int o)
    {
        vars.push_back(o);
        return *this;
    }

    summator& operator << (char *o)
    {
        vars.push_back(atoi(o));
        return *this;
    }

    summator& calc (summator& o)
    {
        int sum = 0;
        while(!vars.empty()){
            sum += vars.front();
            vars.pop_front();
        }
        std::cout << "sum = " << sum;
        return *this;
    }
};

int main(int argc, char* argv[])
{
    summator sum;
    sum << 1 << 2 << "3";
    //sum << summator::calc; // обращение к манипулятору не работает
    sum.calc(sum); // по этому пока вызываю на прямую
    return 0;
}


Сообщение об ошибке, которое возникает при обращении к манипулятору sum << summator::calc; в строке 38
Цитата

1>c:\users\smbd\desktop\test\test.cpp(38) : error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'overloaded-function' (or there is no acceptable conversion)
1>        c:\users\smbd\desktop\test\test.cpp(14): could be 'summator &summator::operator <<(int)'
1>        c:\users\smbd\desktop\test\test.cpp(20): or       'summator &summator::operator <<(char *)'
1>        'summator::calc': function call missing argument list; use '&summator::calc' to create a pointer to member
1>        while trying to match the argument list '(summator)'

Как исправить?

Модератор: не используй тег CODE для цитирования сообщений об ошибках - портится форматирование форума

Это сообщение отредактировал(а) bsa - 28.8.2014, 17:08
PM MAIL   Вверх
borisbn
Дата 28.8.2014, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



В твоём классе не описан оператор <<, который бы получал на вход функцию. Д.б. как-то так

Код
summator& operator << ( summator & (summator::*f)( summator & ) ) {
    (this->*f)( *this );
    return *this;
}


И ещё. Вызов должен быть таким:
Код
    sum << 1 << 2 << "3" << & summator::calc;


Вот - http://ideone.com/aYThBO - подправленный вариант


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
neosapient
Дата 28.8.2014, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



borisbn, спасибо за ответ.

Меня вот что смущает: когда я использую 
std::stringstream ss;
ss << "Hello, World!" << std::endl;

то для std::endl нет никаких добавочных символов, типа
ss << "Hello, World!" << & std::endl;

Как реализовать манипулятор на подобии стандартной библиотеки?
PM MAIL   Вверх
neosapient
Дата 28.8.2014, 23:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Для статичных функций преобразование типов к указателю происходит автоматически.
http://ideone.com/phSsHX

Код

#include <stdlib.h>
#include <list>
#include <iostream>
#include <sstream>

class summator{

    std::list<int> vars;

public:
    summator& operator << (int o)
    {
        vars.push_back(o);
        return *this;
    }

    summator& operator << (const char *o)
    {
        vars.push_back(atoi(o));
        return *this;
    }

     
    summator& operator << ( summator & (*f)( summator & ) )
    {
        (*f)( *this );
        return *this;
    }

    static summator& calc (summator& o)
    {
        int sum = 0;
        while(!o.vars.empty()){
            sum += o.vars.front();
            o.vars.pop_front();
        }
        std::cout << "sum = " << sum;
        return o;
    }
};




int main(int argc, char* argv[])
{
    summator sum;
    sum << 1 << 2 << "3" << summator::calc;
    return 0;
}


Это сообщение отредактировал(а) neosapient - 28.8.2014, 23:57
PM MAIL   Вверх
Alca
Дата 29.8.2014, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



функторы?


--------------------
PM WWW ICQ Skype Jabber   Вверх
neosapient
Дата 25.9.2014, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 672
Регистрация: 16.8.2006

Репутация: нет
Всего: 4



Цитата(Alca @  29.8.2014,  10:04 Найти цитируемый пост)
функторы? 

Приведите пример работы через функторы, чтобы сохранить семантику std::endl
PM MAIL   Вверх
tzirechnoy
Дата 26.9.2014, 08:42 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: -1
Всего: 16



Ну, как в C++ сделать так, чтобы это было Вам ужэ сказали -- так что просто совет.

Возьмите для таких вещей Haskell.

У него есть два большых плюса: первый -- что по факту там такого гораздо большэ, и подобные интеллектуальные упражнения на нём можно проводить очень долго. Вот, например, функцыя на 9 строк: http://www.haskell.org/ghc/docs/6.12.2/htm...ml#permutations, из стандартной библиотеки -- дажэ после того, как чётко сгруппируешь все вызовы и все параметры -- на понимание работы можэт уйти довольно много времени, и лучшэ почитать литературу, чтобы понять, что это они сделали и зачем.

Второй плюс хаскелля -- что вся эта хрень никогда не попадёт в production, и ты сам через пол-года и твои коллеги не будут материться и спотыкаться выясняя, что ещё ты там наизвращал и как надо нестандартно понимать стандартные операторы в конкретно этот файле.
PM MAIL   Вверх
borisbn
Дата 26.9.2014, 08:50 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(neosapient @  25.9.2014,  18:14 Найти цитируемый пост)
 чтобы сохранить семантику std::endl 

Тогда тебе нужно сделать ф-цию calc свободной (как и ф-ция endl). Как-то так
Код

#include <list>
#include <iostream>
#include <sstream>
class summator{
    std::list<int> vars;
public:
    summator& operator << (int o)
    {
        vars.push_back(o);
        return *this;
    }
    summator& operator << (const char *o)
    {
        vars.push_back(atoi(o));
        return *this;
    }
    summator& calc_internal()
    {
        int sum = 0;
        while(!vars.empty()){
            sum += vars.front();
            vars.pop_front();
        }
        std::cout << "sum = " << sum;
        return *this;
    }
    
    summator& operator << ( summator & (f)( summator & ) ) {
        return f( *this );
    }    
};

summator & calc( summator & o )
{
    return o.calc_internal();
}

int main(int argc, char* argv[])
{
    summator sum;
    sum << 1 << 2 << "3" << calc;
    return 0;
}


http://ideone.com/aYThBO

Это сообщение отредактировал(а) borisbn - 26.9.2014, 08:51


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
baldina
Дата 26.9.2014, 11:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



neosapient, 
Код

class summator {
  vector<int> data;
  public:
    summator& operator<<(int rhs) { 
      data.push_back(rhs); 
      return *this;
    }
    int get () const {
       return accumulate (data.begin(), data.end(), 0);
    }
};

int main() {
    summator sum;
    sum << 1 << 2 << 3;
    cout << sum.get();
}

http://ideone.com/fork/9dK9vw
или 

Код

class sequence {
  vector<int> data;

  public:
    sequence& operator<<(int rhs) { 
      data.push_back(rhs);
      return *this;
    }
    sequence& operator<<(function<int(int,int)> binary_op) {
      if (data.size() > 1) {
        int result = accumulate (data.begin()+1, data.end(), *data.begin(), binary_op);
        data.clear();
        data.push_back (result);
      }
      return *this;
    }
    sequence& operator<<(function<int(int)> unary_op) {
      transform(data.begin(), data.end(), data.begin(), unary_op);      
      return *this;
    }

    friend ostream& operator<<(ostream&,const sequence&);
};

ostream& operator<<(ostream& os,const sequence& seq) {
  copy (seq.data.begin(), seq.data.end(), ostream_iterator<int>(os," "));
  return os;
}


auto sum = plus<int>();
auto prod = multiplies<int>();
auto change_sign = [](int x)->int { return -x; };
int sqr (int x) { return x*x; }

int main() {
    sequence seq;
    seq << 1 << 2 << 3 << sum << 4 << 5 << prod << 2 << sqr << -42 << change_sign;
    cout << seq;
}

http://ideone.com/YnvBqL

Это сообщение отредактировал(а) baldina - 26.9.2014, 14:54
PM MAIL   Вверх
NoviceF
Дата 29.9.2014, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 313
Регистрация: 13.3.2012
Где: Ростов-на-Дону

Репутация: 2
Всего: 2



Цитата(tzirechnoy @  26.9.2014,  09:42 Найти цитируемый пост)
как надо нестандартно понимать стандартные операторы в конкретно этот файле. 

Ну может в данном случае это и не очевидно, но сама по себе подобная техника интересна, например, для логгера. Я вот раньше подобное не встречал, хотя в своё время пытался найти инфу на тему.

Так что всем спасибо за инфу и примеры smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0519 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.