Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
#1

binder3 - C++

16.07.2013, 20:35. Просмотров 681. Ответов 18
Метки нет (Все метки)

Здорова!
Есть задачка: "Напишите связывающий адаптер binder3(), который должен связывать второй и третий аргументы трехаргументной функции для получения унарного предиката. Приведите пример полезного применения binder3()."

Ни как не пойму как вернуть из функции указатель на функцию. binder3 как я понимаю должна вернуть указатель на функцию. Как мне определение написать binder3 ???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using std::cout;
using std::endl;
#include <algorithm>
using std::find_if;
 
bool(*)(int a) binder3(bool(*ptr)(int c,int d),int a, int b)
{
    return ptr(a, b);
}
 
//бинарный предикат
bool fun(int a,int b){return (a<b);}
 
//унарный предикат
bool fun(int a){return (a<5);}
 
int main()
{
    int mass[]={1,2,3,4,5,6};
    int* p=find_if(mass,mass+6,fun);
    cout <<*p<<endl;
 
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ViktorKozlov
133 / 125 / 2
Регистрация: 13.12.2012
Сообщений: 293
16.07.2013, 21:41     binder3 #2
Указатель на функцию, которая принимает 2 int'а и возвращает bool, вот так
C++
1
2
3
4
bool (*binder3(bool(*ptr)(int c,int d),int a, int b))(int,int)
{
    return ptr;
}
А вообще, лучше использовать typedef
Kastaneda
Форумчанин
Эксперт С++
4514 / 2856 / 228
Регистрация: 12.12.2009
Сообщений: 7,251
Записей в блоге: 1
Завершенные тесты: 1
16.07.2013, 21:51     binder3 #3
a) binder это не функция, это адаптер. Для "Гуру С++" поясняю - в общем случае это класс с перегруженным оператором ().
б) он не должен ничего возвращать.

Посмотри на реализацию чего-нибудь типа binder2nd. А, если говорить о функции, то посмотри bind2nd.
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
16.07.2013, 23:16  [ТС]     binder3 #4
Kastaneda, мне нужно сделать что бы так было есть допустим функция bool f(int a,int b){return (a<b);} и когда я ее передаю в binded3(f,6,7), то она б наверно делала из этой функции одноаргументную bool f(int a){return (a<7);}
Ну что то вроде binder2nd токо третий аргумент можно куда то прилепить можно такую функцию вернуть bool f(int a){return (a*6<7);} что нибудь придумать. Как это токо сделать?????

Добавлено через 1 минуту
Ладно есть идея как это сделать. Щас попробую мб получится.

Добавлено через 16 минут
Ничо не работает, ладно нужно сделать такую же фигню как binder2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using std::cout;
using std::endl;
#include <algorithm>
using std::find_if;
 
bool binder3(bool(*ptr)(int,int),int a, int b)
{
    return ptr(1,3);
}
 
//бинарный предикат
bool fun(int a,int b){return (a>b);}
 
//унарный предикат
bool fun1(int a){return (a>3);}
 
int main()
{
    int mass[]={1,2,3,4,5,6};
    int* p=find_if(mass,mass+6,binder3(fun,1,3));
    cout <<*p<<endl;
 
    return 0;
}
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
16.07.2013, 23:45     binder3 #5
Цитата Сообщение от ninja2 Посмотреть сообщение
Ничо не работает, ладно нужно сделать такую же фигню как binder2
ну так не тупи, тебе ж сказали:
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
17.07.2013, 00:00  [ТС]     binder3 #6
Цитата Сообщение от Jupiter Посмотреть сообщение
ну так не тупи, тебе ж сказали:
Да посмотрел, там просто оказывается инициализируешь объект, передаешь в алгоритм, в объекте operator перегружен который принимает один аргумент, и вызывает сохраненную функцию с двумя параметрами.

Оказалось вроде просто, а от смогу ли я шаблон написать щас попробую.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:04     binder3 #7
стандартные биндеры старого стандарта достаточно уродские.
если цель - не написать велосипед, то:
в новом стандарте есть лябмды и std::bind
если все в пределах старого стандарта, то тут или написать предикат (класс с operator ()) и правильно его сконструировать или boost::bind.
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
17.07.2013, 00:06  [ТС]     binder3 #8
От красота правдаж???
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using std::cout;
using std::endl;
#include <algorithm>
using std::find_if;
 
class binder3
{
    bool(*ptr)(int,int);
    int val;
public:
    binder3(bool(*ptr1)(int,int),int a):ptr(ptr1),val(a){}
    bool operator()(int i)
    {
        return ptr(i,val);
    }
};
 
//бинарный предикат
bool fun(int a,int b){return (a>b);}
 
//унарный предикат
bool fun1(int a){return (a>3);}
 
int main()
{
    int mass[]={1,2,3,4,5,6};
    int* p=find_if(mass,mass+6,binder3(fun,3));
    cout <<*p<<endl;
 
    return 0;
}
Добавлено через 2 минуты
DU, Да правильно угадал .
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
17.07.2013, 00:10     binder3 #9
шаблон таки ниасилил...это ж так тяжко
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
17.07.2013, 00:13  [ТС]     binder3 #10
Цитата Сообщение от Jupiter Посмотреть сообщение
шаблон таки ниасилил...это ж так тяжко
Да осилил от красавчик:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
using std::cout;
using std::endl;
#include <algorithm>
using std::find_if;
 
template<class T,class C>
class binder3
{
    C(*ptr)(T,T);
    T val;
public:
    binder3(C(*ptr1)(T,T),T a):ptr(ptr1),val(a){}
    bool operator()(T i)
    {
        return ptr(i,val);
    }
};
 
//бинарный предикат
bool fun(int a,int b){return (a>b);}
 
//унарный предикат
bool fun1(int a){return (a>3);}
 
int main()
{
    int mass[]={1,2,3,4,5,6};
    int* p=find_if(mass,mass+6,binder3<int,bool>(fun,3));
    cout <<*p<<endl;
 
    return 0;
}
Еще бы один конструктор преобразования добавить для функциональных объектов и аналог бинд2 готов.
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
17.07.2013, 00:15     binder3 #11
Цитата Сообщение от ninja2 Посмотреть сообщение
C(*ptr)(T,T);
почему параметры имеют одинаковый тип?
почему тип результата bool ?
почему там жеско прописан указатель на функцию?
освободи свой разум, есть лямбды, есть функциональные объекты, они тоже хотят биндить свои параметры
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
17.07.2013, 00:33  [ТС]     binder3 #12
Цитата Сообщение от Jupiter Посмотреть сообщение
почему тип результата bool ?
Там забыл добавить С
Цитата Сообщение от Jupiter Посмотреть сообщение
почему параметры имеют одинаковый тип?
Потому что функция передается с двумя одинаковыми параметрами
Цитата Сообщение от Jupiter Посмотреть сообщение
есть функциональные объекты, они тоже хотят биндить свои параметры
От щас как раз пытаюсь для функциональных объектов как то перегрузить конструктор, но чото ничего не получается.

Добавлено через 10 минут
Jupiter, От для функциональных объектов все вроде работает.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
using std::cout;
using std::endl;
#include <algorithm>
using std::find_if;
 
/*template<class T,class C>
class binder3
{
    C(*ptr)(T,T);
    T val;
    //D obj;
public:
    binder3(C(*ptr1)(T,T),T a):ptr(ptr1),val(a){}
    //binder3(D pr,T a):ptr(0),val(a),obj(pr){}
    C operator()(T i)
    {
        return ptr(i,val);
    }
};*/
 
template<class T,class D,class C>
class binder3
{
    C obj;
    T val;
    //D obj;
public:
    binder3(C& obj1,T a):obj(obj1),val(a){}
    //binder3(D pr,T a):ptr(0),val(a),obj(pr){}
    D operator()(T i)
    {
        return obj(i,val);
    }
};
 
//бинарный предикат
bool fun(int a,int b){return (a>b);}
 
struct pr
{
    bool operator()(int a,int b){return (a>b);}
}pr1;
 
int main()
{
    int mass[]={1,2,3,4,5,6};
    int* p=find_if(mass,mass+6,binder3<int,bool,pr>(pr1,3));
    cout <<*p<<endl;
 
    return 0;
}
Красивые шаблоны получились?

Добавлено через 1 минуту
Да шаблоны тяжело писать.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:35     binder3 #13
вот мой велосипедик:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
template <typename BinPred, typename T>
class binder3 : public std::unary_function<T, bool>
{
  BinPred m_pred;
  T m_value;
 
public:
  binder3(BinPred pred, const T& value)
    : m_pred(pred)
    , m_value(value)
  {
  }
 
  result_type operator () (const argument_type& value) const
  {
    return m_pred(value, m_value);
  }
};
 
template <typename BinPred, typename T>
binder3<BinPred, T> make_binder3(BinPred pred, const T& value)
{
  return binder3<BinPred, T>(pred, value);
}
 
bool funInt(int a, int b)
{
  return a > b;
}
 
bool funLong(long a, long b)
{
  return a > b;
}
 
struct Pred
{
  bool operator () (int a, int b) const
  {
    return a > b;
  }
};
 
int main()
{
  int mass[]={1,2,3,4,5,6};
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(funInt, 3));
    std::cout << *p << std::endl;
  }
 
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(funLong, 3));
    std::cout << *p << std::endl;
  }
 
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(Pred(), 3));
    std::cout << *p << std::endl;
  }
 
  return 0;
}
ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
17.07.2013, 00:48  [ТС]     binder3 #14
DU, молодец шариш.
DU
1482 / 1058 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:50     binder3 #15
если забить на адаптируемость такого предиката, то можно пойти дальше и сделать шаблонным operator ()
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <algorithm>
#include <functional>
#include <iostream>
 
template <typename BinPred, typename T>
class binder3
{
  BinPred m_pred;
  T m_value;
 
public:
  binder3(BinPred pred, const T& value)
    : m_pred(pred)
    , m_value(value)
  {
  }
 
  template <typename U>
  bool operator () (const U& value) const
  {
    return m_pred(value, m_value);
  }
};
 
template <typename BinPred, typename T>
binder3<BinPred, T> make_binder3(BinPred pred, const T& value)
{
  return binder3<BinPred, T>(pred, value);
}
 
bool funInt(int a, int b)
{
  return a > b;
}
 
bool funLong(long a, long b)
{
  return a > b;
}
 
struct Pred
{
  bool operator () (int a, int b) const
  {
    return a > b;
  }
};
 
struct Pred2
{
  bool operator () (int a, const std::string& str) const
  {
    return a > str.length();
  }
};
 
int main()
{
  int mass[]={1,2,3,4,5,6};
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(funInt, 3));
    std::cout << *p << std::endl;
  }
 
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(funLong, 3));
    std::cout << *p << std::endl;
  }
 
  {
    int* p=std::find_if(mass,mass + 6, make_binder3(Pred(), 3));
    std::cout << *p << std::endl;
  }
 
  {
    const char* str = "333";
    int* p=std::find_if(mass,mass + 6, make_binder3(Pred2(), str));
    std::cout << *p << std::endl;
  }
 
  return 0;
}
Yandex
Объявления
17.07.2013, 00:50     binder3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru