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

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

Войти
Регистрация
Восстановить пароль
 
 
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
#1

Шаблоны функции и указатель на функцию передаваемый в функцию - C++

19.05.2017, 05:16. Просмотров 560. Ответов 38
Метки нет (Все метки)

Привет! Вопрос такой: Если я пишу сортировку, например, bubbleSort и хочу помимо массива и его размера передать ещё и указатель на функцию, которая будет отвечать за последовательность сортировки по убыванию или по возрастанию... но сортировка должна специализировать типы данных во время выполнения. Вот как я хотел сделать:
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
template<typename T>
bool ascending(T a, T b)
{
    return a < b;
}
 
template<typename T>
bool descending(T a, T b)
{
    return a > b;
}
 
template<typename T>
void bubbleSort(T* a, const int size, bool(*compare)(T, T))
{
    for(int i = 0; i < size - 1; i++)
    {
        int index = i;
        for(int j = i + 1; j < size; j++)
        {
            if(compare(a[index], a[j])
            {
                index = j;
            }
        }
        T temp = a[i];
        a[i] = a[index];
        a[index] = temp;
    }
}
Конечно же, не получилось, указывает в ошибках на шаблоны во вспомогательных функциях, но как тогда быть с типами во вспомогательных функциях.
В чём моя ошибка, сам не могу разобраться, но ,уверен, что здесь помогут)
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.05.2017, 05:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Шаблоны функции и указатель на функцию передаваемый в функцию (C++):

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

Параметр передаваемый в функцию - C++
Добрый день, уважаемые, посетители форума. Вот я написал быструю сортировку: // quicksort.cpp: главный файл проекта. #include...

Ограничен ли буфер, передаваемый в функцию send - C++
Вопрос: ограничен ли размер буфера, передаваемого в функцию send, размером MTU?

В функцию-метод передать указатель на другую функцию-метод и вызвать через переданный указатель - C++
Друзья! Всем привет. Вот код: class otets { public: void f (void (otets::*p)()); private: void echo_f (){}; ...

Работа с файлом (передать указатель на файл в функцию, вернуть указатель на файл из функции) - C++
Подскажите как передать указатель на файл в функцию, как вернуть указатель на файл из функции. void Open() // из этой функции вернуть...

Указатель на функцию в вызове другой функции - C++
Всем доброе утро. У меня есть вот такая функция. double f(double x) { return x*x; } И мне нужно найти медиану в квадрате. Что я...

38
Antikl
с++
201 / 197 / 56
Регистрация: 15.07.2015
Сообщений: 1,037
Завершенные тесты: 6
19.05.2017, 05:39 #2
C++
1
2
3
4
5
6
7
8
 
template<class T>
void BubbleSort(T* arr, int size) {
  for (int i = 1; i < size; ++i)
    for (int j = size-1; j >= i; --j)
      if (arr[j-1] > arr[j])
        std::swap(arr[j], arr[j-1]);
}
0
GbaLog-
Любитель чаепитий
3078 / 1417 / 342
Регистрация: 24.08.2014
Сообщений: 5,042
Записей в блоге: 1
Завершенные тесты: 2
19.05.2017, 05:49 #3
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 <iostream>
 
template<typename T, typename Func>
void bubbleSort(T * arr, size_t size, Func && compare)
{
    for(int i = 0; i < size - 1; i++)
    {
        int index = i;
        for(int j = i + 1; j < size; j++)
        {
            if(compare(arr[index], arr[j]))
            {
                index = j;
            }
        }
        T temp = arr[i];
        arr[i] = arr[index];
        arr[index] = temp;
    }
}
 
int main()
{
    constexpr size_t size = 3;
    int arr[size]{ 3, 2, 1 };
    
    bubbleSort(arr, size, std::greater<int>());
    
    for (const auto & it : arr)
        std::cout << it << ' ';
}
1
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
19.05.2017, 20:45  [ТС] #4
GbaLog-
Я до таких изысков ещё не дошёл! как-то не совсем то, чего я хотел. Значит, если я определяю шаблон функции сортировки, то вспомогательные функции отсекаются т.к. они не знают, с какими типами данных я работаю, так?
0
GbaLog-
Любитель чаепитий
3078 / 1417 / 342
Регистрация: 24.08.2014
Сообщений: 5,042
Записей в блоге: 1
Завершенные тесты: 2
19.05.2017, 21:04 #5
не понимаю, что у тебя там не работает, у меня так всё работает:
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
#include <iostream>
 
template<typename T>
bool ascending(T a, T b)
{
    return a < b;
}
 
template<typename T>
bool descending(T a, T b)
{
    return a > b;
}
 
template<typename T>
void bubbleSort(T* a, const int size, bool(*compare)(T, T))
{
    for(int i = 0; i < size - 1; i++)
    {
        int index = i;
        for(int j = i + 1; j < size; j++)
        {
            if(compare(a[index], a[j]))
            {
                index = j;
            }
        }
        T temp = a[i];
        a[i] = a[index];
        a[index] = temp;
    }
}
 
int main()
{
    constexpr size_t size = 3;
    int arr[size]{ 3, 2, 1 };
    
    bubbleSort(arr, size, descending);
    
    for (const auto & it : arr)
        std::cout << it << ' ';
}
если у тебя ошибки, то показывай их.
0
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
20.05.2017, 05:25  [ТС] #6
Цитата Сообщение от GbaLog- Посмотреть сообщение
если у тебя ошибки, то показывай их.
D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(43) : error C2958: the left parenthesis '(' found at 'D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(40)' was not matched correctly
D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(62) : error C2896: 'void __cdecl bubbleSort(T *,const int,bool (__cdecl *)(T,T))' : cannot use function template 'bool __cdecl ascending(T,T)' as a function argument
D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(21) : see declaration of 'ascending'
D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(63) : error C2896: 'void __cdecl bubbleSort(T *,const int,bool (__cdecl *)(T,T))' : cannot use function template 'bool __cdecl descending(T,T)' as a function argument
D:\Мои документы\Project\BubbleSort\BubbleSort.cpp(27) : see declaration of 'descending'
Вот ошибки! правда я не использую этих прибамбасов constexpr? просто объявляю, как const int.
вот моя main()
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const size_t size = 5;
    int intArray[size] = {2, 5, 3, 4, 1};
    double doubleArray[size] = {2.2, 5.5, 3.3, 4.4, 1.1};
    
    print(intArray, size);
    cout << endl;
    print(doubleArray, size);
    
        bubbleSort(intArray, size, ascending);
        bubbleSort(doubleArray, size, descending);
 
        print(intArray, size);
        cout << endl;
        print(doubleArray, size);
0
GbaLog-
Любитель чаепитий
3078 / 1417 / 342
Регистрация: 24.08.2014
Сообщений: 5,042
Записей в блоге: 1
Завершенные тесты: 2
20.05.2017, 09:23 #7
Цитата Сообщение от Liss29 Посмотреть сообщение
Вот ошибки!
хм, шаблонную функцию нельзя передавать в качестве указателя на функцию, переделай на функторы.
но вот почему нельзя - я не знаю, а предположения на этот счет не буду говорить, ибо они, скорее всего, окажутся не верными.
переделай на функторы
в твоем случае легче использовать std::greater и std::less.
0
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
20.05.2017, 21:03  [ТС] #8
Цитата Сообщение от GbaLog- Посмотреть сообщение
шаблонную функцию нельзя передавать в качестве указателя на функцию,
Вот это я и хотел узнать. С функторами у меня ничего не получается, не знаком я с ними.
0
GbaLog-
Любитель чаепитий
3078 / 1417 / 342
Регистрация: 24.08.2014
Сообщений: 5,042
Записей в блоге: 1
Завершенные тесты: 2
20.05.2017, 21:35 #9
Функторы, предикаты, функциональные адаптеры, лямбда-функции
0
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
20.05.2017, 23:03  [ТС] #10
За материал, спасибо, прочту, ответ я уже получил, если, конечно, реализовать никак нельзя именно тот код, который я предоставил в самом начале, без этих самых функторов.

Если надо создать некий шаблон класса с типовыи и не типовым параметром, то как реализовывать перегрузку операций, так же как это делается в не шаблонных классах, только с добавлением везде
C++
1
template<typename T, int element>
, так? У меня ничего не получается почему-то вроде везде добавляю это определение. Реализация шаблона класса должна находиться в хедере, правильно? тут тоже мне не совсем всё понятно..
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
#ifndef TEST_H
#define TEST_H
 
#include <iostream>
using std::ostream;
using std::istream;
 
tempalte<typename T, int element>
class Test
{
    friend ostream& operator<<(ostream&, const Test<T,element>&);
friend istream& operator>>(istream&, Test<T, element>&);
public:
Test();
//задесь прототипы
priavte:
      int size;
      T array[element];
};
 
//здесь реализация идёт, так? а #endif на своё месте? 
tempalte<typename T, int element>
Test<T, element>::Test():size((element < 0) ? 10 : element))
{
 
}
 
//......
//в данном случае я всё правильно делаю или что-то упустил?
ostream& Test<T, element>::operator<<(ostream& os, const Test<T, element>& right)
{
       for(int i  = 0; i < right.size; i++)
             os << right.array[i] << ' ';
      return os;
}
#endif
Не могу толком в тему врубиться.

Добавлено через 48 минут
Цитата Сообщение от GbaLog- Посмотреть сообщение
Функторы, предикаты, функциональные адаптеры, лямбда-функции
Из всего текста понадобилась одна строка о том, какой нажо подключить хедер) Да сортирует, но повторюсь это не совсем то, чего я хотел от своей сортировки.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6890 / 3164 / 311
Регистрация: 04.12.2011
Сообщений: 8,772
Записей в блоге: 5
20.05.2017, 23:19 #11
Цитата Сообщение от Liss29 Посмотреть сообщение
Вот это я и хотел узнать.
Шаблонная функция инстанциируется на стадии компиляции. То есть, адреса как такового у инстанса ещё может не быть когда в коде его пытаются взять. Если написать обычную функцию в которой инстанциируется шаблонная, то адрес такой функции вполне можно передать.
Например:
C++
1
2
3
bool pred_char(char lhs, char rhs){
return templ_pred<char>(lhs,rhs);
}
0
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
20.05.2017, 23:49  [ТС] #12
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если написать обычную функцию в которой инстанциируется шаблонная, то адрес такой функции вполне можно передать.
Сейчас узнаю, что такое инстанциируется и тогда, возможно, что-то пойму.
А если серьёзно, то я хотел всего лишь функцию сортировки сделать более универсальной, когда параметры типов передаваемых функции были известны, то всё работало замечательно, вот я и решил, прочитав про шаблоны сделать её, функцию, более-менее гибкой. Я понмаю, что способов решения этой и подобных задачь масса, но я опираюсь на знания, которыми я обладаю на данный момент только и всего.
1
DrOffset
7471 / 4467 / 1015
Регистрация: 30.01.2014
Сообщений: 7,321
20.05.2017, 23:59 #13
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если написать обычную функцию в которой инстанциируется шаблонная, то адрес такой функции вполне можно передать.
Liss29, можно и не писать прослоек. Пример из шапки без изменений + main:
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
template<typename T>
bool ascending(T a, T b)
{
    return a < b;
}
 
template<typename T>
bool descending(T a, T b)
{
    return a > b;
}
 
template<typename T>
void bubbleSort(T* a, const int size, bool (*compare)(T, T))
{
    for(int i = 0; i < size - 1; i++)
    {
        int index = i;
        for(int j = i + 1; j < size; j++)
        {
            if(compare(a[index], a[j]))
            {
                index = j;
            }
        }
        T temp = a[i];
        a[i] = a[index];
        a[index] = temp;
    }
}
 
int main()
{
    const size_t size = 3;
    int arr[size] = { 3, 2, 1 };
    
    bubbleSort(arr, size, &descending<int>); // здесь
    
    for (size_t i = 0; i < size; ++i)
        std::cout << arr[i] << ' ';
}
Демо в онлайн компиляторе: http://rextester.com/FTD78103
4
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6890 / 3164 / 311
Регистрация: 04.12.2011
Сообщений: 8,772
Записей в блоге: 5
21.05.2017, 00:04 #14
Цитата Сообщение от Liss29 Посмотреть сообщение
Сейчас узнаю, что такое инстанциируется и тогда, возможно, что-то пойму.
А если серьёзно, то я хотел всего лишь функцию сортировки сделать более универсальной, когда параметры типов передаваемых функции были известны, то всё работало замечательно, вот я и решил, прочитав про шаблоны сделать её, функцию, более-менее гибкой. Я понмаю, что способов решения этой и подобных задачь масса, но я опираюсь на знания, которыми я обладаю на данный момент только и всего.
Щаблон это не простой код. Это описатель для генерации кода. То есть компилятор глядя на шаблон и на вызов генерирует то, что мы пишем когда определяем функцию явно. В том, что я написал нет ни слова правды, но так проще представить для начала.
А вообще:
Желание создать обобщения для сравнения штука спорная. В принципе сам предикат является частью описания конкретного типа и его обобщение это обобщение на уровне какого-то типа, всё равно. Если совсем уж философски, то выбор из таких параметров как
имя, фамилия, рост, вес, цвет, глубина, температура
первых четырёх формирует объект именно потому, что ученик / ученица класса сравнимы и отличимы именно этими параметрами. А температура (обычно) не является предикатом с высокой селективность по отношению к группе людей. Если они живые и не больные.
То есть, предикат это глубоко внутренняя логика типа и обобщать можно только на уровне типа (в иерархии в том числе). imho
1
Liss29
25 / 14 / 2
Регистрация: 18.11.2012
Сообщений: 543
Завершенные тесты: 1
21.05.2017, 03:45  [ТС] #15
DrOffset
Это уже ближе к истине. Но я сделал по совету выше с
C++
1
std::less<>() std::greate<>()
короче говоря не суть важно, вот ещё бы из
C++
1
&descending<int>
убрать этот <int> во тогда будет то, что я хотел. Но это уже не совсем то, так как это сделал не я.

Добавлено через 19 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Щаблон это не простой код.
Это я понимаю.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Желание создать обобщения для сравнения штука спорная.
Это имеется ввиду для ascending и discending, но тогда так же ошибки формируются.
0
21.05.2017, 03:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.05.2017, 03:45
Привет! Вот еще темы с ответами:

Указатель на функцию в качестве параметра функции - C++
ln(1-x)+sinx необходимо создать программу демонстрирующую возможность использования указателя на некоторую функцию в качестве параметра...

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

Передача массива в функцию используя указатель на функцию - C++
У меня имеется готовая программа без передачи функции в функцию указателем, мне нужно передать функцию ввода масива в функцию его обработки...

Указатель на функцию с аргументами, как аргумент другой функции - C++
У меня есть некая функция, которая принимает как аргумент другую функцию typedef void(*func_type)(); start(func_type...


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

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

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