С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 5.00
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
#1

Шаблон указателя на функцию и шаблоны функций - C++

12.03.2014, 10:42. Просмотров 1414. Ответов 14
Метки нет (Все метки)

Подскажите пожалуйста, в чём проблема? Не смог разобраться.

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
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
 
template <typename T>
typedef bool (* TFunc)(T, T);   // пытаюсь создать шаблон указателя на функцию.
template <typename T>
bool Asc(T left, T right)       // функция, которая пригодится для сортировки по возростанию.
{ return left > right; }
template <typename T>
bool Desc(T left, T right)      // функция, которая пригодится для сортировки по убыванию.
{ return left < right; }
template <typename T>
void sort(T *pArr, int size, TFunc pFunc)   // сама сортировка (пузырьковым методом).
{
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size - 1 - i; ++j)
            if (pFunc(pArr[j], pArr[j+1]))
            {
                T temp = pArr[j];
                pArr[j] = pArr[j+1];
                pArr[j+1] = temp;
            }
}
int main()
{
    srand(unsigned (time(0)));
    int n = 10;
    int *pArr = new int [n];        // создается массив.
    for (int i = 0; i < n; ++i)
        pArr[i] = rand()%11;
    for (int i = 0; i < n; ++i)     // отображение массива.
        cout << pArr[i] << " ";
    cout << endl;
    cout << "Enter 1 to ordinate array in ascent\n"
            "and 2 - in descent:\n";
    int c;
    while (cin >> c)                // выбор 1 для сортировки по возростанию и 2 - по убыванию.
    {
        if (c == 1 || c == 2)
            break;
        cout << "Enter correct number! Try again:\n";
    }
    if (c == 1)
        sort (pArr, n, Asc);
    else
        sort (pArr, n, Desc);
    for (int i = 0; i < n; ++i)     // отображение отсортированного массива.
        cout << pArr[i] << " ";
    cout << endl;
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.03.2014, 10:42
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблон указателя на функцию и шаблоны функций (C++):

Шаблоны функций, Ошибка: для использования класса шаблон требуется список аргументов шаблон - C++
Есть у меня 3 структуры Трамвай , Троллейбус , Автобус. Для автобуса определены функции (работают) Троллейбус и Трамвай одинаковые поля...

Шаблоны функций. Можно ли задать шаблон мэйна - C++
Понятно что нельзя. В этом чудном участке кода, в мэйн вводимые данные кастятся к инту. Как это можно обойти?#include&lt;iostream&gt; using...

Шаблон указателя на функцию - C++
Надо создать шаблон, который бы генерировал функцию, вызывающую другую функцию, которую я передал ей в шаблоне. Что - то похожее на это,...

Написать функцию используя шаблоны функций, организуйте ее работу с целыми и вещественными числами - C++
Написать функцию используя шаблоны функций, организуйте ее работу с целыми и вещественными числами. Организовать ее вызов в главной функции...

Написать функцию, используя шаблоны функций, организуйте ее работу с целыми и вещественными числами - C++
Написать функцию, используя шаблоны функций, организуйте ее работу с целыми и вещественными числами. Организовать ее вызов в главной...

Шаблон RAII замены указателя на функцию - C++
шаблон raii замены указателя на фукнцию допустим имеется набор указателей на функции разных типов и существует потребность временно,...

14
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
12.03.2014, 10:58 #2
Цитата Сообщение от montkay Посмотреть сообщение
Подскажите пожалуйста, в чём проблема?
Эт Вы нам скажите в чем проблема то.
Цитата Сообщение от montkay Посмотреть сообщение
для сортировки по возростанию.
Цитата Сообщение от montkay Посмотреть сообщение
для сортировки по убыванию.
std::greater
std::less

C++
1
2
3
4
    if (c == 1)
        sort (pArr, n, Asc);
    else
        sort (pArr, n, Desc);
Asc и Desc - шаблоны
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
12.03.2014, 11:01 #3
А вы подумайте, что вы делаете. Для разных функций (с разными реализациями) вы объявляете один и тот же псевдоним. Т.е. как компилятор разберется в такой записи:
C++
1
2
3
4
5
6
//.....
bool f1(int, int);
bool f2(float, float);
//.....
TFunc = f1;
TFunc = f2;
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
12.03.2014, 11:02 #4
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 "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
 
template <typename T>
bool Asc(T left, T right)       // функция, которая пригодится для сортировки по возростанию.
{ return left > right; }
template <typename T>
bool Desc(T left, T right)      // функция, которая пригодится для сортировки по убыванию.
{ return left < right; }
template <typename T,typename U>
void sort(T *pArr, int size, U pFunc)   // сама сортировка (пузырьковым методом).
{
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size - 1 - i; ++j)
            if (pFunc(pArr[j], pArr[j+1]))
            {
                T temp = pArr[j];
                pArr[j] = pArr[j+1];
                pArr[j+1] = temp;
            }
}
int main()
{
    srand(unsigned (time(0)));
    int n = 10;
    int *pArr = new int [n];        // создается массив.
    for (int i = 0; i < n; ++i)
        pArr[i] = rand()%11;
    for (int i = 0; i < n; ++i)     // отображение массива.
        cout << pArr[i] << " ";
    cout << endl;
    cout << "Enter 1 to ordinate array in ascent\n"
            "and 2 - in descent:\n";
    int c;
    while (cin >> c)                // выбор 1 для сортировки по возростанию и 2 - по убыванию.
    {
        if (c == 1 || c == 2)
            break;
        cout << "Enter correct number! Try again:\n";
    }
    if (c == 1)
        sort (pArr, n, Asc<int>);
    else
        sort (pArr, n, Desc<int>);
    for (int i = 0; i < n; ++i)     // отображение отсортированного массива.
        cout << pArr[i] << " ";
    cout << endl;
    return 0;
}
1
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
12.03.2014, 12:24  [ТС] #5
Croessmah, виноват - не указал саму проблему =) Проблема находится в следующем:
C++
1
typedef bool (* TFunc)(T, T);
Именно в этом месте происходит ошибка при компиляции. А потом соответственно и в функции
C++
1
void sort(T *pArr, int size, TFunc pFunc)
Добавлено через 6 минут
Ilot, но ведь присваивание происходить не одновременно, а с помощью разветвления:
Цитата Сообщение от montkay Посмотреть сообщение
C++
1
2
3
4
if (c == 1)
     sort (pArr, n, Asc);
   else
     sort (pArr, n, Desc);
Добавлено через 7 минут
Сейчас я понял, что именно нужно сделать - правильно отобразить шаблон указателя на функцию:
C++
1
typedef bool (* TFunc)(T, T);
Именно из-за этого места не работают другие функции, мне кажется. Просто функции должны принимать любые типы данных - символы, числа целые и с плавающей точкой.
0
John Prick
824 / 757 / 152
Регистрация: 27.07.2012
Сообщений: 2,156
Завершенные тесты: 3
12.03.2014, 12:24 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Тайпдефы шаблонными не могут быть.
1
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
12.03.2014, 12:30 #7
Цитата Сообщение от montkay Посмотреть сообщение
Ilot, но ведь присваивание происходить не одновременно, а с помощью разветвления:
И что? Вы не поняли сути. Объявляя замену типа шаблонным вы тем самым различным шаблонам присваиваете одно и тоже имя. Это почти тоже самое, что и сделать вот так:
C++
1
2
bool (* TFunc)(int, int);
bool (* TFunc)(float, float);
Поэтому компилятор этого не допускает.
1
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
12.03.2014, 12:37  [ТС] #8
John Prick, Вы бесспорно правы =) Прочитал в интернете: "если нельзя, но очень хочется, то можно". Здесь нельзя применить какой-нибудь метод, чтобы сделать указатель на функцию шаблонным?

Добавлено через 1 минуту
Ilot, действительно какой-то бред получается =) Спасибо!
0
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
12.03.2014, 12:42 #9
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Чем не устраивает код из поста #4?
Цитата Сообщение от montkay Посмотреть сообщение
Здесь нельзя применить какой-нибудь метод, чтобы сделать указатель на функцию шаблонным?
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
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
 
template < typename T >
struct TFunc {
   typedef bool (*type)(T,T) ;
} ;
 
template <typename T>
bool Asc(T left, T right)       // функция, которая пригодится для сортировки по возростанию.
{ return left > right; }
template <typename T>
bool Desc(T left, T right)      // функция, которая пригодится для сортировки по убыванию.
{ return left < right; }
template <typename T>
void sort(T *pArr, int size, typename TFunc<T>::type pFunc)   // сама сортировка (пузырьковым методом).
{
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size - 1 - i; ++j)
            if (pFunc(pArr[j], pArr[j+1]))
            {
                T temp = pArr[j];
                pArr[j] = pArr[j+1];
                pArr[j+1] = temp;
            }
}
 
int main()
{
    srand(unsigned (time(0)));
    int n = 10;
    int *pArr = new int [n];        // создается массив.
    for (int i = 0; i < n; ++i)
        pArr[i] = rand()%11;
    for (int i = 0; i < n; ++i)     // отображение массива.
        cout << pArr[i] << " ";
    cout << endl;
    cout << "Enter 1 to ordinate array in ascent\n"
            "and 2 - in descent:\n";
    int c;
    while (cin >> c)                // выбор 1 для сортировки по возростанию и 2 - по убыванию.
    {
        if (c == 1 || c == 2)
            break;
        cout << "Enter correct number! Try again:\n";
    }
    if (c == 1)
        sort (pArr, n, Asc<int>);
    else
        sort (pArr, n, Desc<int>);
    for (int i = 0; i < n; ++i)     // отображение отсортированного массива.
        cout << pArr[i] << " ";
    cout << endl;
    return 0;
}
1
John Prick
824 / 757 / 152
Регистрация: 27.07.2012
Сообщений: 2,156
Завершенные тесты: 3
12.03.2014, 12:46 #10
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template <typename T>
struct pointer_to_function_template
{
    typedef bool (*TFunc)(T, T);
}
 
bool func1(int, int);
bool func2(double, double);
bool func3(string, string);
 
pointer_to_function_template<int>::TFunc pFunc1 = func1;
pointer_to_function_template<double>::TFunc pFunc2 = func2;
pointer_to_function_template<string>::TFunc pFunc3 = func3;
2
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
12.03.2014, 12:49  [ТС] #11
Croessmah, хороший код, но есть одно моё пожелание - хочется, чтобы шаблонный указатель принимал любые типы данных. А у Вашем коде нужно будет каждый раз изменять тип данных:
Цитата Сообщение от Croessmah Посмотреть сообщение
C++
1
2
3
4
if (c == 1)
* * * * sort (pArr, n, Asc<int>);
* * else
* * * * sort (pArr, n, Desc<int>);
А так всё хорошо, согласен =)
0
John Prick
824 / 757 / 152
Регистрация: 27.07.2012
Сообщений: 2,156
Завершенные тесты: 3
12.03.2014, 12:52 #12
montkay, зачем вам в вашей задача вообще нужен шаблонный указатель на функцию? Шаблонная функция sort и без этого отлично разберётся, какой ей передаётся тип указателя.
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
12.03.2014, 12:55 #13
Цитата Сообщение от montkay Посмотреть сообщение
Croessmah, хороший код, но есть одно моё пожелание - хочется, чтобы шаблонный указатель принимал любые типы данных. А у Вашем коде нужно будет каждый раз изменять тип данных:
Ну так уберите параметры шаблона. Для вызова функции они не обязательны:
C++
1
2
3
4
    if (c == 1)
        sort (pArr, n, Asc);
    else
        sort (pArr, n, Desc);
1
Croessmah
Ушел
Эксперт CЭксперт С++
13558 / 7708 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
12.03.2014, 13:18 #14
Цитата Сообщение от montkay Посмотреть сообщение
А у Вашем коде нужно будет каждый раз изменять тип данных
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
template <typename T>
bool Asc(T left, T right)       // функция, которая пригодится для сортировки по возростанию.
{ return left > right; }
template <typename T>
bool Desc(T left, T right)      // функция, которая пригодится для сортировки по убыванию.
{ return left < right; }
template <typename T >
void sort(T *pArr, int size, bool (*pFunc)(T,T) )   // сама сортировка (пузырьковым методом).
{
    for (int i = 0; i < size; ++i)
        for (int j = 0; j < size - 1 - i; ++j)
            if (pFunc(pArr[j], pArr[j+1]))
            {
                T temp = pArr[j];
                pArr[j] = pArr[j+1];
                pArr[j+1] = temp;
            }
}
 
int main()
{
    srand(unsigned (time(0)));
    int n = 10;
    int *pArr = new int [n];        // создается массив.
    for (int i = 0; i < n; ++i)
        pArr[i] = rand()%11;
    for (int i = 0; i < n; ++i)     // отображение массива.
        cout << pArr[i] << " ";
    cout << endl;
    cout << "Enter 1 to ordinate array in ascent\n"
            "and 2 - in descent:\n";
    int c;
    while (cin >> c)                // выбор 1 для сортировки по возростанию и 2 - по убыванию.
    {
        if (c == 1 || c == 2)
            break;
        cout << "enter correct number! Try again:\n";
    }
    if (c == 1)
        sort (pArr, n, Asc);
    else
        sort (pArr, n, Desc);
    for (int i = 0; i < n; ++i)     // отображение отсортированного массива.
        cout << pArr[i] << " ";
    cout << endl;
    return 0;
}
1
montkay
10 / 10 / 8
Регистрация: 19.02.2014
Сообщений: 72
12.03.2014, 13:21  [ТС] #15
Croessmah, спасибо за помощь!
0
12.03.2014, 13:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.03.2014, 13:21
Привет! Вот еще темы с ответами:

Как сделать функцию от указателя на класс и указателя на метод? - C++
Не получается сделать функцию, параметрами которой являются указатель на класс и на метод. Обращаться к классу нужно именно по указателю,...

Зачем передавать в функцию X указатель на callback функцию, если последняя ВНЕШНЯЯ и вызовется БЕЗО ВСЯКОГО УКАЗАТЕЛЯ? - C++
Собсно. То есть ребята, вот пример отсюда: http://www.cplusplus.com/reference/algorithm/count_if/ // count_if example #include...

Передача указателя на шаблонную функцию в другую функцию - C++
Пишу тест для нескольких улучшений квиксорта с измерением времени. Функция benchmark принимает итераторы для диапазона элементов, указатель...

Шаблоны функции и указатель на функцию передаваемый в функцию - C++
Привет! Вопрос такой: Если я пишу сортировку, например, bubbleSort и хочу помимо массива и его размера передать ещё и указатель на функцию,...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

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