Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
1

binder3

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

Author24 — интернет-сервис помощи студентам
Здорова!
Есть задачка: "Напишите связывающий адаптер 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;
}
0
138 / 130 / 59
Регистрация: 13.12.2012
Сообщений: 293
16.07.2013, 21:41 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
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
16.07.2013, 21:51 3
a) binder это не функция, это адаптер. Для "Гуру С++" поясняю - в общем случае это класс с перегруженным оператором ().
б) он не должен ничего возвращать.

Посмотри на реализацию чего-нибудь типа binder2nd. А, если говорить о функции, то посмотри bind2nd.
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
16.07.2013, 23:16  [ТС] 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;
}
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
16.07.2013, 23:45 5
Цитата Сообщение от ninja2 Посмотреть сообщение
Ничо не работает, ладно нужно сделать такую же фигню как binder2
ну так не тупи, тебе ж сказали:
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
17.07.2013, 00:00  [ТС] 6
Цитата Сообщение от Jupiter Посмотреть сообщение
ну так не тупи, тебе ж сказали:
Да посмотрел, там просто оказывается инициализируешь объект, передаешь в алгоритм, в объекте operator перегружен который принимает один аргумент, и вызывает сохраненную функцию с двумя параметрами.

Оказалось вроде просто, а от смогу ли я шаблон написать щас попробую.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:04 7
стандартные биндеры старого стандарта достаточно уродские.
если цель - не написать велосипед, то:
в новом стандарте есть лябмды и std::bind
если все в пределах старого стандарта, то тут или написать предикат (класс с operator ()) и правильно его сконструировать или boost::bind.
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
17.07.2013, 00:06  [ТС] 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, Да правильно угадал .
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
17.07.2013, 00:10 9
шаблон таки ниасилил...это ж так тяжко
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
17.07.2013, 00:13  [ТС] 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 готов.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
17.07.2013, 00:15 11
Цитата Сообщение от ninja2 Посмотреть сообщение
C(*ptr)(T,T);
почему параметры имеют одинаковый тип?
почему тип результата bool ?
почему там жеско прописан указатель на функцию?
освободи свой разум, есть лямбды, есть функциональные объекты, они тоже хотят биндить свои параметры
0
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
17.07.2013, 00:33  [ТС] 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 минуту
Да шаблоны тяжело писать.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:35 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;
}
1
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
17.07.2013, 00:48  [ТС] 14
DU, молодец шариш.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 00:50 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;
}
1
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
17.07.2013, 09:35 16
DU, ninja2, так по заданию же нужно сделать binder3 (т.е. предикат должен принимать 3 аргумента), а я у вас вижу что-то типа binder2.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
17.07.2013, 10:06 17
С поддержкой функций обычных (чем кстати не занимется ни bind2nd, ни bind1st) будет менее симпатично.

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
#include <functional>
 
template<typename Operation>
struct binder3_t : 
   public std::unary_function<typename Operation::first_argument_type, typename Operation::result_type>
{
public:
   binder3_t(Operation op, const typename Operation::second_argument_type& s,
         const typename Operation::third_argument_type& t) :
      operation(op), second(s), third(t)
   {
   }
   typename Operation::result_type operator () (const typename Operation::first_argument_type& arg)
   {
      return operation(arg, second, third);
   }
private:
   Operation operation;
   typename Operation::second_argument_type second;
   typename Operation::third_argument_type third;
};
 
template<typename Operation, typename T1, typename T2>
binder3_t<Operation> binder3(Operation op, const T1& s, const T2& t)
{
   typename Operation::second_argument_type second(s);
   typename Operation::third_argument_type third(t);
   return binder3_t<Operation>(op, second, third);
}
 
template<typename T0, typename T1, typename T2, typename R>
struct ternary_function
{
   typedef T0 first_argument_type;
   typedef T1 second_argument_type;
   typedef T2 third_argument_type;
   typedef R result_type;
};
 
// test
 
struct multiply : ternary_function<int, int, int, int>
{
   result_type operator () (int f, int s, int t)
   {
      return f * s * t;
   }
};
 
#include <iostream>
#include <vector>
#include <algorithm>
 
int main()
{
   std::vector<int> v = {1};
   std::transform(v.begin(), v.end(), v.begin(), binder3(multiply(), 2, 3));
   std::cout << v.front() << std::endl;
}
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
17.07.2013, 10:10 18
так по заданию же нужно сделать binder3
кстати да. я в задание даже не посмотрел. получился биндер2.
биндер 3 делается по аналогии. еще нужно от захардкоженного типа возвращаемого значения избавится, которое можно выводить либо внутри самого биндера3, либо в make функции, либо задавать явно.
0
В астрале
Эксперт С++
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
17.07.2013, 11:10 19
DU,
еще нужно от захардкоженного типа возвращаемого значения избавится, которое можно выводить либо внутри самого биндера3, либо в make функции
А подробнее можно? Я вот что-то придумать не могу, чтобы это было хоть как-то красиво

Один из интересных вариантов - использовать boost::function_types

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
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
 
namespace desc = boost::function_types;
 
template<typename Operation>
struct binder3_t
{
   static_assert(desc::function_arity<Operation>::value == 3,
         "only ternary functions can be accepted");
   typedef typename desc::result_type<Operation>::type result_t;
   typedef typename desc::parameter_types<Operation>::type args_t;
   typedef typename boost::mpl::at_c<args_t, 0>::type first_t;
   typedef typename boost::mpl::at_c<args_t, 1>::type second_t;
   typedef typename boost::mpl::at_c<args_t, 2>::type third_t;
public:
   template<typename T1, typename T2>
   binder3_t(Operation op, const T1& s, const T2& t) :
      operation(op), second(s), third(t)
   {
   }
   result_t operator () (const first_t& arg) const
   {
      return operation(arg, second, third);
   }
private:
   Operation operation;
   second_t second;
   third_t third;
};
Но работает только с обычными функциями.
1
17.07.2013, 11:10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru