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

mem_fun и mem_fun_ref - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.92
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 00:47     mem_fun и mem_fun_ref #1
Здорова! Есть задачка : "Реализуйте и протестируйте четыре функции mem_fun() и mem_fun_ref() (параграф 18.4.4.2)."
Ну там наверно ошиблись не 4 а две функции да пусть две функции будет. Ну и как же мне их реализовать? Чем они хоть отличаются? Это похоже одни и те же функции, токо первая с указателями работает, а вторая с объектами ли хз.
В общем свои нужно написать, наверно свой шаблон нужно написать, а как его делать я даже не представляю. Похоже тяжелая задачка.

Добавлено через 1 минуту
Кто не знает эти функции делают функциональные объект из членов класса.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2013, 00:47     mem_fun и mem_fun_ref
Посмотрите здесь:

C++ вызов неконстантной функции класса в mem_fun_ref
STL: не работает mem_fun_ref C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
13.07.2013, 00:48     mem_fun и mem_fun_ref #2
http://www.cplusplus.com/reference/f...un/?kw=mem_fun
http://www.cplusplus.com/reference/f...l/mem_fun_ref/
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,917
Записей в блоге: 2
Завершенные тесты: 1
13.07.2013, 00:49     mem_fun и mem_fun_ref #3
Цитата Сообщение от ninja2 Посмотреть сообщение
Чем они хоть отличаются?
Тем, что обращение к функции-члену по указателю и по ссылке отличаются
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
13.07.2013, 00:50     mem_fun и mem_fun_ref #4
Цитата Сообщение от ninja2 Посмотреть сообщение
Ну там наверно ошиблись не 4 а две функции
4 минимум - надо константность учитывать.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 00:55  [ТС]     mem_fun и mem_fun_ref #5
ForEveR, Да я эти примеры разобрал, не сильно они мне помогли. Щас свой кусочек шаблона из книги покажу.

Добавлено через 35 секунд
gray_fox, Там такой хорошо запутанный шаблон, двойной какой то он.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
13.07.2013, 00:55     mem_fun и mem_fun_ref #6
Цитата Сообщение от ninja2 Посмотреть сообщение
наверно свой шаблон нужно написать
Скорее 4 шаблона класса + "генераторы"
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
13.07.2013, 00:58     mem_fun и mem_fun_ref #7
Реализация mem_fun для неконстантной функции без аргументов.

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
#include <iostream>
#include <vector>
#include <algorithm>
 
template<typename S, typename T>
struct mem_fun_t
{
    typedef S (T::*fp_t)();
public:
    mem_fun_t(fp_t fp) : pointer(fp)
    {
    }
    S operator () (T* p)
    {
        return (p->*pointer)();
    }
private:
    fp_t pointer;
};
 
template<typename S, typename T>
mem_fun_t<S, T> mem_fun(S (T::*fp)())
{
    return mem_fun_t<S, T>(fp);
}
 
struct test
{
    void call() { std::cout << "called" << std::endl; }
};
 
int main()
{
    std::vector<test*> vec;
    vec.push_back(new test());
    vec.push_back(new test());
    std::for_each(vec.begin(), vec.end(), mem_fun(&test::call));
    for (std::vector<test*>::iterator pos = vec.begin(); pos != vec.end(); ++pos)
    {
        delete *pos;
    }
}
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 01:05  [ТС]     mem_fun и mem_fun_ref #8
ForEveR, Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
13.07.2013, 01:15     mem_fun и mem_fun_ref #9
Цитата Сообщение от ninja2 Посмотреть сообщение
ForEveR, Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
Там тоже самое, только operator () будет ссылку принимать, да для вызова метода другой синтаксис...
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,917
Записей в блоге: 2
Завершенные тесты: 1
13.07.2013, 01:17     mem_fun и mem_fun_ref #10
Цитата Сообщение от ninja2 Посмотреть сообщение
Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
Всё аналогично: http://ideone.com/5en5I2
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 01:25  [ТС]     mem_fun и mem_fun_ref #11
От примерчик который в книге, он как бы работает, но когда пишешь Mem_fun с большой буквы то не работает.
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
#include <iostream>
using std::cout;
using std::endl;
#include <functional>
using std::unary_function;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <algorithm>
using std::transform;
 
template<class R, class T> class mem_fun_t : public unary_function<T*,R>
{
    R(T::*pmf)();
public:
    explicit mem_fun_t(R(T::*p)()) :pmf(p){}
 
    R operator()(T* p)const {return (p->*pmf)();}//вызов по указателю
};
 
template<class R,class T> mem_fun_t<R,T> mem_fun(R(T::*f)())
{
    return mem_fun_t<R,T>(f);
}
 
int main()
{
    vector<string*> v;
    v.push_back(new string("one"));
    v.push_back(new string("twooo"));
    int l[2];
    
    transform(v.begin(),v.end(),l,mem_fun(&string::length));
 
    for(int i=0;i<2;i++)
        cout <<l[i]<<' ';//3 5
    cout <<endl;
 
    return 0;
}
видимо std::mem_fun вызывается, а нам же видимо нужно свой написать
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
#include <iostream>
using std::cout;
using std::endl;
#include <functional>
using std::unary_function;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <algorithm>
using std::transform;
 
template<class R, class T> class Mem_fun_t : public unary_function<T*,R>
{
    R(T::*pmf)();
public:
    explicit Mem_fun_t(R(T::*p)()) :pmf(p){}
 
    R operator()(T* p)const {return (p->*pmf)();}//вызов по указателю
};
 
template<class R,class T> Mem_fun_t<R,T> Mem_fun(R(T::*f)())
{
    return Mem_fun_t<R,T>(f);
}
 
int main()
{
    vector<string*> v;
    v.push_back(new string("one"));
    v.push_back(new string("twooo"));
    int l[2];
    
    transform(v.begin(),v.end(),l,Mem_fun(&string::length));
 
    for(int i=0;i<2;i++)
        cout <<l[i]<<' ';//3 5
    cout <<endl;
 
    return 0;
}
ничего не работает, не компелируется, где то шаблон не правильно написан. ????

Добавлено через 57 секунд
ForEveR, Щас проверю пример форевера мб я погорячился плюс поставить

Добавлено через 2 минуты
ForEveR, нет работает как нужно молодец
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
#include <iostream>
#include <vector>
#include <algorithm>
 
template<typename S, typename T>
struct Mem_fun_t
{
    typedef S (T::*fp_t)();
public:
    Mem_fun_t(fp_t fp) : pointer(fp)
    {
    }
    S operator () (T* p)
    {
        return (p->*pointer)();
    }
private:
    fp_t pointer;
};
 
template<typename S, typename T>
Mem_fun_t<S, T> Mem_fun(S (T::*fp)())
{
    return Mem_fun_t<S, T>(fp);
}
 
struct test
{
    void call() { std::cout << "called" << std::endl; }
};
 
int main()
{
    std::vector<test*> vec;
    vec.push_back(new test());
    vec.push_back(new test());
    std::for_each(vec.begin(), vec.end(), Mem_fun(&test::call));
    for (std::vector<test*>::iterator pos = vec.begin(); pos != vec.end(); ++pos)
    {
        delete *pos;
    }
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
13.07.2013, 01:52     mem_fun и mem_fun_ref #12
ninja2, 1 вариант не писать using namespace std.
2 вариант - написать
C++
1
transform(v.begin(),v.end(),l,::mem_fun(&string::length));
Croessmah
13.07.2013, 01:54
  #13

Не по теме:

ForEveR, первый вариант приятнее намного

gray_fox
13.07.2013, 01:54
  #14

Не по теме:

Цитата Сообщение от gray_fox Посмотреть сообщение
Скорее 4 шаблона класса
наврал, 2 будет достаточно...

ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 02:03  [ТС]     mem_fun и mem_fun_ref #15
ForEveR, Да я уже понял что в transform ошибка, твой пример переделал, щас попробую с usnin namespace свой запустить.

Добавлено через 31 секунду
Цитата Сообщение от gray_fox Посмотреть сообщение
наврал, 2 будет достаточно...
ну бывает .

Добавлено через 8 минут
ForEveR, да нет если я так напишу
Цитата Сообщение от ForEveR Посмотреть сообщение
transform(v.begin(),v.end(),l,::mem_fun(&string::length));
то тогда моя функция Mem_fun вызываться не будет.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
13.07.2013, 02:06     mem_fun и mem_fun_ref #16
gray_fox, В STL как раз их 4. И без хитрых ухищрений два не сделать, ибо
C++
1
2
3
4
S (T::*f)();
S (T::*f)() const;
S (T::*f)(A);
S (T::*f)(A) const;
Стерто. Неверно прочитал. Да там вызывается не std-шная, она не может быть вызвана, ибо нету подходящего using-а.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 02:07  [ТС]     mem_fun и mem_fun_ref #17
ForEveR, и твой примерчик для transform тоже не работает, ну да ладно хоть для for_each работает, тоже хорошо.
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
#include <iostream>
using std::cout;
using std::endl;
#include <functional>
using std::unary_function;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <algorithm>
using std::transform;
using namespace::std;
 
template<typename S, typename T>
struct Mem_fun_t
{
    typedef S (T::*fp_t)();
public:
    Mem_fun_t(fp_t fp) : pointer(fp)
    {
    }
    S operator () (T* p)
    {
        return (p->*pointer)();
    }
private:
    fp_t pointer;
};
 
template<typename S, typename T>
Mem_fun_t<S, T> Mem_fun(S (T::*fp)())
{
    return Mem_fun_t<S, T>(fp);
}
 
int main()
{
    vector<string*> v;
    v.push_back(new string("one"));
    v.push_back(new string("twooo"));
    int l[2];
    
    transform(v.begin(),v.end(),l,Mem_fun(&string::length));
 
    for(int i=0;i<2;i++)
        cout <<l[i]<<' ';//3 5
    cout <<endl;
 
    return 0;
}
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
13.07.2013, 02:12     mem_fun и mem_fun_ref #18
ninja2, Конечно, не работает, функция length у std::string константная, потому хранить мы должны в случаях константных функций

C++
1
typedef S (T::*fp_t) () const;
Ну и mem_fun должен быть правильно перегружен

C++
1
2
3
4
5
template<typename S, typename T>
mem_fun_const<S, T> mem_fun(S (T::*fp)() const)
{
   return mem_fun_const<S, T>(fp);
}
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
13.07.2013, 03:03  [ТС]     mem_fun и mem_fun_ref #19
А как два шаблона определить???? Отак не получается.
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
#include <iostream>
using std::cout;
using std::endl;
#include <functional>
using std::unary_function;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <algorithm>
using std::transform;
//using namespace::std;
 
//для константных
template<class R, class T> class Mem_fun_t : public unary_function<T*,R>
{
    R(T::*pmf)() const;
public:
    explicit Mem_fun_t(R(T::*p)() const) :pmf(p){}
 
    R operator()(T* p)const {return (p->*pmf)();}//вызов по указателю
};
 
template<class R,class T> Mem_fun_t<R,T> Mem_fun( R(T::*f)() const)
{
    cout <<"mu tyt const"<<endl;//не вызовется моя
    return Mem_fun_t<R,T>(f);
}
 
//для не константных
template<class A, class B> class Mem_fun_t : public unary_function<A*,B>
{
    A(T::*pmf)();
public:
    explicit Mem_fun_t(A(T::*p)()) :pmf(p){}
 
    A operator()(B* p)const {return (p->*pmf)();}//вызов по указателю
};
 
template<class R,class T> Mem_fun_t<R,T> Mem_fun( R(T::*f)())
{
    cout <<"mu tyt ne const"<<endl;//не вызовется моя
    return Mem_fun_t<R,T>(f);
}
 
int main()
{
    vector<string*> v;
    v.push_back(new string("one"));
    v.push_back(new string("twooo"));
    int l[2];
    
    transform(v.begin(),v.end(),l,Mem_fun(&string::length));
 
    for(int i=0;i<2;i++)
        cout <<l[i]<<' ';//3 5
    cout <<endl;
 
    return 0;
}
Добавлено через 15 минут
Ладно тупанул я проехали тему, там просто перегрузить функции и все.
Olivеr
 Аватар для Olivеr
411 / 407 / 13
Регистрация: 06.10.2011
Сообщений: 830
13.07.2013, 04:11     mem_fun и mem_fun_ref #20
По поводу константных функций:
можно ограничиться одним классом, но это, как по мне, плохая идея
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
#include <iostream>
 
template <typename Type, typename ReturnType>
struct mem_fun_ptr_t
{
    typedef ReturnType (Type::*Func)();
    Func func;
public:
    mem_fun_ptr_t(Func f):
        func(f) {}
    ReturnType operator () (Type *p) { return (p->*func)(); }
    ReturnType operator () (Type *p) const { return (p->*func)(); }
};
 
template <typename T, typename R>
mem_fun_ptr_t<T, R> mem_fun_ptr(R (T::*Func)() const)
{
    typedef R (T::*f)();
    f x = reinterpret_cast<f>(Func);
    return mem_fun_ptr_t<T, R>(x);
}
 
int main()
{
    std::string str = "Hello";
    auto x = mem_fun_ptr(&std::string::length);
    std::cout << x(&str);
    return 0;
}
http://ideone.com/bO0oOt
Yandex
Объявления
13.07.2013, 04:11     mem_fun и mem_fun_ref
Ответ Создать тему
Опции темы

Текущее время: 20:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru