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

mem_fun и mem_fun_ref

13.07.2013, 00:47. Показов 6140. Ответов 24
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здорова! Есть задачка : "Реализуйте и протестируйте четыре функции mem_fun() и mem_fun_ref() (параграф 18.4.4.2)."
Ну там наверно ошиблись не 4 а две функции да пусть две функции будет. Ну и как же мне их реализовать? Чем они хоть отличаются? Это похоже одни и те же функции, токо первая с указателями работает, а вторая с объектами ли хз.
В общем свои нужно написать, наверно свой шаблон нужно написать, а как его делать я даже не представляю. Похоже тяжелая задачка.

Добавлено через 1 минуту
Кто не знает эти функции делают функциональные объект из членов класса.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.07.2013, 00:47
Ответы с готовыми решениями:

STL: не работает mem_fun_ref
Здравствуйте! Который час корплю над этим кодом и не могу разобраться ptr_fun работает безукоризненно mem_fun_ref ни в какую ...

Вызов неконстантной функции класса в mem_fun_ref
Привет. мне нужно вызвать функцию класса в mem_fun_ref, но ей, как известно требуется чтобы передаваемая функция класса была...

Std::bind, std::mem_fun, std::mem_fn
В чем разница между функциями std::bind, std::mem_fun, std::mem_fn?


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

Или воспользуйтесь поиском по форуму:
24
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
13.07.2013, 00:48
http://www.cplusplus.com/refer... kw=mem_fun
http://www.cplusplus.com/refer... m_fun_ref/
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
13.07.2013, 00:49
Цитата Сообщение от ninja2 Посмотреть сообщение
Чем они хоть отличаются?
Тем, что обращение к функции-члену по указателю и по ссылке отличаются
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
13.07.2013, 00:50
Цитата Сообщение от ninja2 Посмотреть сообщение
Ну там наверно ошиблись не 4 а две функции
4 минимум - надо константность учитывать.
1
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 00:55  [ТС]
ForEveR, Да я эти примеры разобрал, не сильно они мне помогли. Щас свой кусочек шаблона из книги покажу.

Добавлено через 35 секунд
gray_fox, Там такой хорошо запутанный шаблон, двойной какой то он.
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
13.07.2013, 00:55
Цитата Сообщение от ninja2 Посмотреть сообщение
наверно свой шаблон нужно написать
Скорее 4 шаблона класса + "генераторы"
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
13.07.2013, 00:58
Реализация 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;
    }
}
1
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 01:05  [ТС]
ForEveR, Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
13.07.2013, 01:15
Цитата Сообщение от ninja2 Посмотреть сообщение
ForEveR, Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
Там тоже самое, только operator () будет ссылку принимать, да для вызова метода другой синтаксис...
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
13.07.2013, 01:17
Цитата Сообщение от ninja2 Посмотреть сообщение
Еще бы неплохо бы было б mem_fun_ref реализацию б увидеть
Всё аналогично: http://ideone.com/5en5I2
1
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 01:25  [ТС]
От примерчик который в книге, он как бы работает, но когда пишешь 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;
    }
}
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
13.07.2013, 01:52
ninja2, 1 вариант не писать using namespace std.
2 вариант - написать
C++
1
transform(v.begin(),v.end(),l,::mem_fun(&string::length));
1
13.07.2013, 01:54

Не по теме:

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

0
13.07.2013, 01:54

Не по теме:

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

0
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 02:03  [ТС]
ForEveR, Да я уже понял что в transform ошибка, твой пример переделал, щас попробую с usnin namespace свой запустить.

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

Добавлено через 8 минут
ForEveR, да нет если я так напишу
Цитата Сообщение от ForEveR Посмотреть сообщение
transform(v.begin(),v.end(),l,::mem_fun( &string::length));
то тогда моя функция Mem_fun вызываться не будет.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
13.07.2013, 02:06
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-а.
0
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 02:07  [ТС]
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;
}
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
13.07.2013, 02:12
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);
}
1
 Аватар для ninja2
979 / 196 / 33
Регистрация: 26.09.2012
Сообщений: 2,041
13.07.2013, 03:03  [ТС]
А как два шаблона определить???? Отак не получается.
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 минут
Ладно тупанул я проехали тему, там просто перегрузить функции и все.
0
 Аватар для Olivеr
415 / 411 / 95
Регистрация: 06.10.2011
Сообщений: 832
13.07.2013, 04:11
По поводу константных функций:
можно ограничиться одним классом, но это, как по мне, плохая идея
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
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Ответ Создать тему
Новые блоги и статьи
BOINC: 22 года — и всё ещё работает
Programma_Boinc 12.03.2026
BOINC: 22 года — и всё ещё работает Дэвид Андерсон написал ретроспективу. Кратко: в 2001 году он ушёл из United Devices, где был CTO, и за несколько месяцев написал ядро BOINC — клиент, сервер,. . .
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru