Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
1

Передача шаблонной функции в качестве параметра

02.04.2021, 09:41. Показов 4079. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нужно передать функцию Maximum_Array_Element тип которой может меняться (int, double....) в функцию Maximum_Element_Of_Two_Arrays, заранее спасибо

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <iostream>
#include <cstdlib>  // для rand(), для srand().
#include <ctime> // для time().
 
using namespace std;
#define WINDOWS "russian"
#define LINUX "ru_RU.UTF-8"
void set_header();
 
// Предварительные объявление функций
///===================================================================
 
template <typename Type_Func, typename T1, typename T2> // Инициализации массива
Type_Func Init_Array(T1* array, T2 size_array);
 
///===================================================================
 
template <typename Type_Func, typename T1, typename T2> // Вывода массива в консоль
Type_Func Print_Array(T1* array, T2 size_array);
 
///===================================================================
// Вычисление максимума массива
template <typename Type_Func, typename T1, typename T2>
Type_Func Maximum_Array_Element(T1* Array, T2 size_Array);
 
template <typename Type_Func_1, typename T1, typename T2, typename T3, typename Type_Func_2>
Type_Func_1 Maximum_Element_Of_Two_Arrays(T1* ptr_Array_A, T2 size_Array_A, T3* ptr_Array_B, T2 size_Array_B,
    Type_Func_2(*Maximum_Array_Element)()); ///// 
 
///===================================================================
 
int main()
{
    setlocale(LC_ALL, WINDOWS);
    cout << endl;
    set_header();
    cout << endl;
 
    srand(static_cast<size_t>(time(NULL)));
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    // Объявление и инициализация переменных
 
    int menu = 0;
 
    const size_t size_Array_A = 10;
    int Array_A[size_Array_A];
    int* ptr_Array_A = Array_A;
 
    const size_t size_Array_B = 5;
    float Array_B[size_Array_B];
    float* ptr_Array_B = Array_B;
 
    ///===================================================================
    ///===================================================================
    // Вывод массивов в консоль
 
    cout << "\tВывод массива A: " << endl;
    Init_Array<void, int, size_t>(Array_A, size_Array_A);
    Print_Array<void, int, size_t>(Array_A, size_Array_A);
    cout << endl << endl;
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    cout << "\tВывод массива B: " << endl;
    Init_Array<void, float, size_t>(Array_B, size_Array_B);
    Print_Array<void, float, size_t>(Array_B, size_Array_B);
    cout << endl << endl;
 
 
    cout << Maximum_Element_Of_Two_Arrays/*<int, size_t, float, size_t>*/(ptr_Array_A, size_Array_A, ptr_Array_B, size_Array_B, Maximum_Array_Element();
 
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
 
    cout << endl;
    system("pause");
    system("cls");
    return(0);
}
 
void set_header()
{
    cout << endl;
    cout << "\n\t\t\tОсновы программирования на языке С++.\n";
    cout << "\t\t\tТема:  Указатели. Указатель на функцию.\n\n";
    cout << endl;
}
 
template <typename Type_Func, typename T1, typename T2>
Type_Func Init_Array(T1* array, T2 size_array) { // Функция инициализации  массива
    for (T2 i = 0; i < size_array; i++)
        array[i] = rand() % 100;
}
 
template <typename Type_Func, typename T1, typename T2>
Type_Func Print_Array(T1* array, T2 size_array) { // Функция вывода массива
    for (T2 i = 0; i < size_array; i++)
        cout << "\t" << array[i];
}
 
template <typename Type_Func, typename T1, typename T2>
Type_Func Maximum_Array_Element(T1* Array, T2 size_Array)
{
    T1 temp = Array[0];
    for (T2 i = 0; i < size_Array; i++)
        if (temp < Array[i])
            temp = Array[i];
    return temp;
}
 
template <typename Type_Func_1, typename T1, typename T2, typename T3, typename Type_Func_2>
Type_Func_1 Maximum_Element_Of_Two_Arrays(T1* ptr_Array_A, T2 size_Array_A, T3* ptr_Array_B, T2 size_Array_B,
    Type_Func_2(*Maximum_Array_Element)())
{
    T1 temp_A = Maximum_Array_Element(ptr_Array_A, size_Array_A);
    T3 temp_B = Maximum_Array_Element(ptr_Array_B, size_Array_B);
    auto result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.04.2021, 09:41
Ответы с готовыми решениями:

Передача функции в качестве параметра
Как передать функцию с параметрами в transform? Т.е., например, мне надо из каждого числа вектора...

Передача функции в качестве параметра
#include &lt;iostream&gt; #include &lt;math.h&gt; using namespace std; double f(double x) { return...

Передача CString в качестве параметра функции
Добрый всем вечер! Мучает один вопрос, на который не могу найти ответ. Как наилучшим образом...

Передача лямбда-функции в качестве параметра
Коллеги, доброго всем времени суток. Помогите, пожалуйста, с такой проблемой. Передаю функцию в...

19
440 / 283 / 183
Регистрация: 23.06.2018
Сообщений: 651
02.04.2021, 13:03 2
Лучший ответ Сообщение было отмечено solvo23 как решение

Решение

Ох... Скажите, а в чём смысл делать так много параметров шаблона?
1. В инициализации и тем более выводе массива вы ничего не возвращаете, там Type_Func не нужен, достаточно просто void возвращать.
2. В Maximum_Array_Element достаточно вернуть T1.
3. И раз уж я начал придираться к параметрам, то есть ли вообще смысл делать шаблонным размер массива? Проверки на отрицательные числа нет, использовать дробные числа это извращение, а создавать разные функции потому что где-то можно сэкономить несколько байт... Сомнительное решение.

Также из скромных ошибок:
1. Type_Func_2(*Maximum_Array_Element)() является указателем на функцию, которая ничего не принимает.
2. Maximum_Element_Of_Two_Arrays/*<int, size_t, float, size_t>*/(ptr_Array_A, size_Array_A, ptr_Array_B, size_Array_B, Maximum_Array_Element(); вы открыли лишнюю скобку + из-за вашего Type_Func_1 вы не сможете автоматически вывести шаблон.

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

Игнорируя мои жалобы к изобилию параметров шаблона, вот решение:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// Вызов
Maximum_Element_Of_Two_Arrays<float, int, size_t, float>(ptr_Array_A, size_Array_A, ptr_Array_B, size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
 
// Функция
template <typename Type_Func_1, typename T1, typename T2, typename T3>
Type_Func_1 Maximum_Element_Of_Two_Arrays(T1* ptr_Array_A, T2 size_Array_A, T3* ptr_Array_B, T2 size_Array_B,
    T1(*Maximum_A)(T1*, T2), T3(*Maximum_B)(T3*, T2))
{
    T1 temp_A = Maximum_A(ptr_Array_A, size_Array_A);
    T3 temp_B = Maximum_B(ptr_Array_B, size_Array_B);
    Type_Func_1 result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
1
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
02.04.2021, 14:01  [ТС] 3
Просто на занятиях дали меньше чем в статье которую прочитал вчера (о шаблонных функциях)
Поэтому и пытаюсь усвоить все что видел в этой статье, заодно решить задачу по передаче функции в функцию
Спасибо за рекомендации пойду переосмысливать информацию
0
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
03.04.2021, 15:28  [ТС] 4
Попытался привести код в соответствии с рекомендациями
Все вроде работает, но
хотел немного по другому
Функция
Maximum_Element_Of_Two_Arrays должна принять в качестве аргументов две функции Maximum_Array_Element тип данных у первой int у второй double и вернуть результат в том типе который принимает result и вот это, то не получается

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iomanip> // для setprecision(), для setw() 
#include <iostream>
#include <cstdlib>  // для rand(), для srand().
#include <ctime> // для time().
#include <Windows.h>
 
using namespace std;
#define WINDOWS "russian"
#define LINUX "ru_RU.UTF-8"
void set_header();
 
// Предварительные объявление функций:
///===================================================================
 
template <typename T>
void Init_Array(T* Array, size_t Size_Array); // Инициализации массива
 
///===================================================================
 
template <typename T>
void Print_Array(T* Array, size_t Size_Array); // Вывода массива в консоль
 
///===================================================================
 
template <typename T>
T Maximum_Array_Element(T* Array, size_t Size_Array); // Вычисление максимального элемента массива
 
template <typename Type_Func, typename T1, typename T2>
Type_Func Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t));
 
///===================================================================
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    //setlocale(LC_ALL, WINDOWS);
    cout << endl;
    set_header();
    cout << endl;
    
    srand(static_cast<size_t>(time(NULL)));
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    // Объявление и инициализация переменных
 
    int menu = 0;
 
    const size_t Size_Array_A = 20;
    int* Array_A = new int[Size_Array_A];
    //int* ptr_Array_A = Array_A;
 
    const size_t Size_Array_B = 10;
    double* Array_B = new double[Size_Array_B];
    //double* ptr_Array_B = Array_B;
 
    ///===================================================================
    ///===================================================================
    // Вывод массивов в консоль
 
    cout << "\tВывод массива A: " << endl;
    Init_Array(Array_A, Size_Array_A);
    Print_Array(Array_A, Size_Array_A);
    cout << endl << endl;
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    cout << "\tВывод массива B: " << endl;
    Init_Array(Array_B, Size_Array_B);
    Print_Array(Array_B, Size_Array_B);
    cout << endl << endl;
 
    auto a = Maximum_Array_Element(Array_A, Size_Array_A);
    cout << typeid(a).name() << endl;
    cout << Maximum_Array_Element(Array_A, Size_Array_A) << endl;
 
    auto b = Maximum_Array_Element(Array_B, Size_Array_B);
    cout << typeid(b).name() << endl;
    cout << Maximum_Array_Element(Array_B, Size_Array_B) << endl;
 
    cout << Maximum_Element_Of_Two_Arrays<double, int, double>(Array_A, Size_Array_A, Array_B, Size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
   
    //cout << sizeof(Array_B);
    //cout << typeid(Array_B).name();
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
 
    cout << endl;
    system("pause");
    system("cls");
    return(0);
}
 
void set_header()
{
    cout << endl;
    cout << "\n\t\t\tОсновы программирования на языке С++.\n";
    cout << "\t\t\tТема:  Указатели. Указатель на функцию.\n\n";
    cout << "\tНаписать программу, которая содержит функцию Action, принимающую в качестве аргумента, указатели на два массива (А и В) и размеры массивов, а также указатель на функцию. Пользователю отображается меню, в котором он может выбрать max, min, avg. Если выбран max - передается указатель на функцию, которая ищет максимум, если выбран min - передается указатель на функцию, которая ищет минимум, если выбран avg - передается указатель на функцию, которая ищет среднее. Возвращаемое значение функции Action результат выбора пользователя max, min, avg.\n";
    cout << endl;
}
 
template <typename T>
void Init_Array(T* Array, size_t Size_Array) { // Функция инициализации  массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(int)) Array[i] = rand() % 100;
        if (sizeof(T) == sizeof(double)) Array[i] = rand() % 10000 / 100.00;
        if (sizeof(T) == sizeof(char)) Array[i] = 'a' + rand() % 26 - 32 * (rand() % 2); //65-90 (A-Z) & 97-122 (a-z)
    }
}
 
template <typename T>
void Print_Array(T* Array, size_t Size_Array) { // Функция вывода массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(double)) {
            cout.flags(ios::fixed);
            cout << setprecision(2);
        }
        cout << "\t" << Array[i];
        if ((i + 1) % 10 == 0) cout << "\n";
    }
}
 
template <typename T>
T Maximum_Array_Element(T* Array, size_t Size_Array)
{
    T temp = Array[0];
    for (size_t i = 0; i < Size_Array; i++)
        if (temp < Array[i]) temp = Array[i];
    return temp;
}
 
template <typename Type_Func, typename T1, typename T2>
Type_Func Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    auto result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
0
440 / 283 / 183
Регистрация: 23.06.2018
Сообщений: 651
03.04.2021, 17:09 5
Технически, в С++14 есть вывод возвращаемого типа, для этого надо просто поставить auto, но есть 2 проблемы:
1. Функция должна быть определена до её вызова (а не просто объявлена, как у вас).
2. Если вам придётся сдавать этот код, то подумайте, оценит ли принимающий такой трюк и будет ли доступен С++14 при демонстрации (на текущий момент, в VS2019 это минимальная версия стандарта, но не уверен на счёт остального).
Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// Функция
template <typename T1, typename T2>
auto Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    auto result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
 
// Вызов (да, теперь вы можете не уточнять параметры шаблона)
Maximum_Element_Of_Two_Arrays(Array_A, Size_Array_A, Array_B, Size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
1
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
03.04.2021, 21:21  [ТС] 6
Ошибка C3779 "Maximum_Element_Of_Two_Arrays": функцию, возвращающую "auto" нельзя использовать, предварительно не определив
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <iomanip> // для setprecision(), для setw() 
#include <iostream>
#include <cstdlib>  // для rand(), для srand().
#include <ctime> // для time().
#include <Windows.h>
 
using namespace std;
#define WINDOWS "russian"
#define LINUX "ru_RU.UTF-8"
void set_header();
 
// Предварительные объявление функций:
///===================================================================
 
template <typename T>
void Init_Array(T* Array, size_t Size_Array); // Инициализации массива
 
///===================================================================
 
template <typename T>
void Print_Array(T* Array, size_t Size_Array); // Вывода массива в консоль
 
///===================================================================
 
template <typename T>
T Maximum_Array_Element(T* Array, size_t Size_Array); // Вычисление максимального элемента массива
 
template <typename T1, typename T2>
auto Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t));
 
///===================================================================
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    //setlocale(LC_ALL, WINDOWS);
    cout << endl;
    set_header();
    cout << endl;
    
    srand(static_cast<size_t>(time(NULL)));
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    // Объявление и инициализация переменных
 
    int menu = 0;
 
    const size_t Size_Array_A = 20;
    int* Array_A = new int[Size_Array_A];
    //int* ptr_Array_A = Array_A;
 
    const size_t Size_Array_B = 10;
    double* Array_B = new double[Size_Array_B];
    //double* ptr_Array_B = Array_B;
 
    ///===================================================================
    ///===================================================================
    // Вывод массивов в консоль
 
    cout << "\tВывод массива A: " << endl;
    Init_Array(Array_A, Size_Array_A);
    Print_Array(Array_A, Size_Array_A);
    cout << endl << endl;
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    cout << "\tВывод массива B: " << endl;
    Init_Array(Array_B, Size_Array_B);
    Print_Array(Array_B, Size_Array_B);
    cout << endl << endl;
 
    auto a = Maximum_Array_Element(Array_A, Size_Array_A);
    cout << typeid(a).name() << endl;
    cout << Maximum_Array_Element(Array_A, Size_Array_A) << endl;
 
    auto b = Maximum_Array_Element(Array_B, Size_Array_B);
    cout << typeid(b).name() << endl;
    cout << Maximum_Array_Element(Array_B, Size_Array_B) << endl;
 
    cout << Maximum_Element_Of_Two_Arrays(Array_A, Size_Array_A, Array_B, Size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
   
    //cout << sizeof(Array_B);
    //cout << typeid(Array_B).name();
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
 
    cout << endl;
    system("pause");
    system("cls");
    return(0);
}
 
void set_header()
{
    cout << endl;
    cout << "\n\t\t\tОсновы программирования на языке С++.\n";
    cout << "\t\t\tТема:  Указатели. Указатель на функцию.\n\n";
    cout << "\tНаписать программу, которая содержит функцию Action, принимающую в качестве аргумента, указатели на два массива (А и В) и размеры массивов, а также указатель на функцию. Пользователю отображается меню, в котором он может выбрать max, min, avg. Если выбран max - передается указатель на функцию, которая ищет максимум, если выбран min - передается указатель на функцию, которая ищет минимум, если выбран avg - передается указатель на функцию, которая ищет среднее. Возвращаемое значение функции Action результат выбора пользователя max, min, avg.\n";
    cout << endl;
}
 
template <typename T>
void Init_Array(T* Array, size_t Size_Array) { // Функция инициализации  массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(int)) Array[i] = rand() % 100;
        if (sizeof(T) == sizeof(double)) Array[i] = rand() % 10000 / 100.00;
        if (sizeof(T) == sizeof(char)) Array[i] = 'a' + rand() % 26 - 32 * (rand() % 2); //65-90 (A-Z) & 97-122 (a-z)
    }
}
 
template <typename T>
void Print_Array(T* Array, size_t Size_Array) { // Функция вывода массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(double)) {
            cout.flags(ios::fixed);
            cout << setprecision(2);
        }
        cout << "\t" << Array[i];
        if ((i + 1) % 10 == 0) cout << "\n";
    }
}
 
template <typename T>
T Maximum_Array_Element(T* Array, size_t Size_Array)
{
    T temp = Array[0];
    for (size_t i = 0; i < Size_Array; i++)
        if (temp < Array[i]) temp = Array[i];
    return temp;
}
 
template <typename T1, typename T2>
auto Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    auto result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
0
фрилансер
5504 / 5099 / 1048
Регистрация: 11.10.2019
Сообщений: 13,366
03.04.2021, 21:30 7
solvo23, а зачем тебе вообще эти предварительные, они только загромождают код

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <iomanip> // для setprecision(), для setw() 
#include <iostream>
#include <cstdlib>  // для rand(), для srand().
#include <ctime> // для time().
#include <Windows.h>
 
using namespace std;
#define WINDOWS "russian"
#define LINUX "ru_RU.UTF-8"
 
void set_header()
{
    cout << endl;
    cout << "\n\t\t\tОсновы программирования на языке С++.\n";
    cout << "\t\t\tТема:  Указатели. Указатель на функцию.\n\n";
    cout << "\tНаписать программу, которая содержит функцию Action, принимающую в качестве аргумента, указатели на два массива (А и В) и размеры массивов, а также указатель на функцию. Пользователю отображается меню, в котором он может выбрать max, min, avg. Если выбран max - передается указатель на функцию, которая ищет максимум, если выбран min - передается указатель на функцию, которая ищет минимум, если выбран avg - передается указатель на функцию, которая ищет среднее. Возвращаемое значение функции Action результат выбора пользователя max, min, avg.\n";
    cout << endl;
}
 
template <typename T>
void Init_Array(T* Array, size_t Size_Array) { // Функция инициализации  массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(int)) Array[i] = rand() % 100;
        if (sizeof(T) == sizeof(double)) Array[i] = rand() % 10000 / 100.00;
        if (sizeof(T) == sizeof(char)) Array[i] = 'a' + rand() % 26 - 32 * (rand() % 2); //65-90 (A-Z) & 97-122 (a-z)
    }
}
 
template <typename T>
void Print_Array(T* Array, size_t Size_Array) { // Функция вывода массива
    for (size_t i = 0; i < Size_Array; i++) {
        if (sizeof(T) == sizeof(double)) {
            cout.flags(ios::fixed);
            cout << setprecision(2);
        }
        cout << "\t" << Array[i];
        if ((i + 1) % 10 == 0) cout << "\n";
    }
}
 
template <typename T>
T Maximum_Array_Element(T* Array, size_t Size_Array)
{
    T temp = Array[0];
    for (size_t i = 0; i < Size_Array; i++)
        if (temp < Array[i]) temp = Array[i];
    return temp;
}
 
template <typename T1, typename T2>
auto Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    auto result = (temp_A > temp_B) ? temp_A : temp_B;
    return result;
}
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
    //setlocale(LC_ALL, WINDOWS);
    cout << endl;
    set_header();
    cout << endl;
    
    srand(static_cast<size_t>(time(NULL)));
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    // Объявление и инициализация переменных
 
    int menu = 0;
 
    const size_t Size_Array_A = 20;
    int* Array_A = new int[Size_Array_A];
    //int* ptr_Array_A = Array_A;
 
    const size_t Size_Array_B = 10;
    double* Array_B = new double[Size_Array_B];
    //double* ptr_Array_B = Array_B;
 
    ///===================================================================
    ///===================================================================
    // Вывод массивов в консоль
 
    cout << "\tВывод массива A: " << endl;
    Init_Array(Array_A, Size_Array_A);
    Print_Array(Array_A, Size_Array_A);
    cout << endl << endl;
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
    cout << "\tВывод массива B: " << endl;
    Init_Array(Array_B, Size_Array_B);
    Print_Array(Array_B, Size_Array_B);
    cout << endl << endl;
 
    auto a = Maximum_Array_Element(Array_A, Size_Array_A);
    cout << typeid(a).name() << endl;
    cout << Maximum_Array_Element(Array_A, Size_Array_A) << endl;
 
    auto b = Maximum_Array_Element(Array_B, Size_Array_B);
    cout << typeid(b).name() << endl;
    cout << Maximum_Array_Element(Array_B, Size_Array_B) << endl;
 
    cout << Maximum_Element_Of_Two_Arrays(Array_A, Size_Array_A, Array_B, Size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
   
    //cout << sizeof(Array_B);
    //cout << typeid(Array_B).name();
    ///===================================================================
    cout << "===================================================" << endl << endl;
    ///===================================================================
 
    cout << endl;
    system("pause");
    system("cls");
    return(0);
}
1
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
03.04.2021, 21:54  [ТС] 8
Все равно double возвращает
0
фрилансер
5504 / 5099 / 1048
Регистрация: 11.10.2019
Сообщений: 13,366
03.04.2021, 22:11 9
Цитата Сообщение от solvo23 Посмотреть сообщение
вернуть результат в том типе который принимает result

может, так?

C++
1
2
3
4
5
6
7
8
template <typename T1, typename T2>
decltype(auto) Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    return (temp_A > temp_B) ? temp_A : temp_B;
}
Добавлено через 2 минуты
Цитата Сообщение от solvo23 Посмотреть сообщение
Все равно double возвращает
дык, а как же оно вернёт не double, если выражение
Цитата Сообщение от Алексей1153 Посмотреть сообщение
(temp_A > temp_B) ? temp_A : temp_B;
"примет на вход" int и double, на "выходе" будет именно double

как же ещё то ?

Добавлено через 1 минуту
тогда вот так

C++
1
2
3
4
5
6
7
8
template <typename T1, typename T2>
T1 Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    return T1( (temp_A > temp_B) ? temp_A : temp_B );
}
Добавлено через 1 минуту
подправил
1
1709 / 1109 / 337
Регистрация: 25.01.2019
Сообщений: 2,910
03.04.2021, 23:53 10
Цитата Сообщение от solvo23 Посмотреть сообщение
Все равно double возвращает
Ну дык оно и нормально. Смысл-то не в самих типах, а в уходе от сужающих преобразований.
Или, например, выйдет что temp_A == 20, temp_B == 20.0 - и что с этим делать тогда?

Можно, конечно, костылями покидаться:
Кликните здесь для просмотра всего текста
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
#include <iostream>
 
template <class T>
T* foomax(T* arr, size_t size)
{
    T* max = &arr[0];
    while (--size) if (*max < arr[size]) max = &arr[size];
    return max;
}
 
template <class T, class Q>
void* max_of_2arr(T* t, size_t Tsize, Q* q, size_t Qsize, T* (*tfoo)(T*, size_t), Q* (*qfoo)(Q*, size_t))
{
    T* tmax = tfoo(t, Tsize);
    Q* qmax = qfoo(q, Qsize);
 
    return (*tmax > *qmax ? static_cast<void*>(tmax) : static_cast<void*>(qmax));
}
 
int main()
{
    const size_t dsize = 3;
    const size_t isize = 3;
    double darr[dsize] = { 10.0, 2.2, 4.9 };
    int iarr[isize] = { 3, 20, 1 };
 
    void* x = max_of_2arr(darr, dsize, iarr, isize, foomax, foomax);
 
    if (x >= darr && x < (darr + dsize))
    {
        double res = *static_cast<double*>(x);
        std::cout << res << " " << typeid(res).name() << "\n";
    } else {
        int res = *static_cast<int*>(x);
        std::cout << res << " " << typeid(res).name() << "\n";
    }
 
    system("pause");
    return 0;
}
, но это уже на грани как-то.
0
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,306
04.04.2021, 00:58 11
Цитата Сообщение от Folian Посмотреть сообщение
на грани как-то.
По-моему это уже за гранью.

Я бы еще понял, если бы предложено было так как-то:
C++
1
2
3
4
5
6
7
8
9
10
11
template <typename T1, typename T2>
auto Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    if constexpr(temp_A > temp_B) 
        return temp_A;
    else
        return temp_B;
}
0
1709 / 1109 / 337
Регистрация: 25.01.2019
Сообщений: 2,910
04.04.2021, 05:25 12
Цитата Сообщение от DrOffset Посмотреть сообщение
так как-то:
А как-нибудь так можно в принципе?

Это ж как, без неконстант до самой свадьбы?
0
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
04.04.2021, 07:47  [ТС] 13
Не сразу понял это
"Функция должна быть определена до её вызова (а не просто объявлена, как у вас)."
Это означает что я должен не использовать предварительное объявление функции, а определить ее до функции main?
Если так, то почти все получается
0
фрилансер
5504 / 5099 / 1048
Регистрация: 11.10.2019
Сообщений: 13,366
04.04.2021, 07:53 14
solvo23, если у функции в качестве типа возврата указан auto или decltype(auto), то тип выводится по первому встреченному в теле функции return , при этом все последующие returnы должны возвращать тип, который конвертируется в первый выведенный.

в предварительном объявлении нет тела функции, соответственно возвращаемый тип не может быть выведен для этого предварительного объявления
0
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
04.04.2021, 08:54  [ТС] 15
А выражении подобном этому принимает значение наибольшего типа данных?
auto temp_C = (temp_A > temp_B) ? temp_A : temp_B;
0
фрилансер
5504 / 5099 / 1048
Регистрация: 11.10.2019
Сообщений: 13,366
04.04.2021, 08:59 16
Цитата Сообщение от solvo23 Посмотреть сообщение
наибольшего
наиширейший )
1
2 / 2 / 0
Регистрация: 05.02.2021
Сообщений: 158
04.04.2021, 09:02  [ТС] 17
Понятно я то хотел что бы среди значения переменной double и значения переменной int выбрало одно и вернуло тип данных выбранного значения, получается нельзя
0
фрилансер
5504 / 5099 / 1048
Регистрация: 11.10.2019
Сообщений: 13,366
04.04.2021, 09:07 18
solvo23,

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 <variant>
 
...
...
 
template <typename T1, typename T2>
std::variant<T1,T2> Maximum_Element_Of_Two_Arrays(T1* Array_A, size_t Size_Array_A, T2* Array_B, size_t Size_Array_B,
    T1(*Maximum_A)(T1*, size_t), T2(*Maximum_B)(T2*, size_t))
{
    T1 temp_A = Maximum_A(Array_A, Size_Array_A);
    T2 temp_B = Maximum_B(Array_B, Size_Array_B);
    if(temp_A > temp_B)
    {
        return temp_A;   
    }
    else
    {
        return temp_B;
    }
}
 
...
...
 
    auto result= Maximum_Element_Of_Two_Arrays(Array_A, Size_Array_A, Array_B, Size_Array_B, Maximum_Array_Element, Maximum_Array_Element);
    std::visit([](auto value)
    {
        cout << value;
    },result);
2
18902 / 9860 / 2410
Регистрация: 30.01.2014
Сообщений: 17,306
04.04.2021, 11:44 19
Цитата Сообщение от Folian Посмотреть сообщение
А как-нибудь так можно в принципе?
Это ж как, без неконстант до самой свадьбы?
В принципе - можно. Можно ли в этом конкретном случае - не важно, смысл примера в другом: тип у нас статический, на ходу он не меняется. Это самое важное, что нужно понимать при программировании на С++.
А я лишь хотел показать, что уход от статической типизации в сторону неконтролируемых умолчаний - это совсем не хорошо. Мы должны либо переносить контроль за типизацией на этап компиляции (как у меня в примере), либо переносить его на этап исполнения (как в примере #18).
1
1709 / 1109 / 337
Регистрация: 25.01.2019
Сообщений: 2,910
04.04.2021, 13:58 20
Цитата Сообщение от DrOffset Посмотреть сообщение
Можно ли в этом конкретном случае - не важно
Это да, такой фокус у меня получилось провернуть только для глобальных констант.
Цитата Сообщение от DrOffset Посмотреть сообщение
тип у нас статический, на ходу он не меняется
Тут-то собака и закопана.
Цитата Сообщение от DrOffset Посмотреть сообщение
это совсем не хорошо
Согласен, тыкать войдами и кастами во всякое - это "на худой конец", и пример плохой.
Посещали мысли про кортежи, обёртки над union или нечтом, исходящим из чего-то вроде
C++
1
2
3
4
5
struct {
T* t = nullptr;
Q* q = nullptr;
/*....*/
};
мне казалось тут обсуждается невозможность перегрузки по выходному типу и хотелось продемонстрировать это поярче, но почему-то счёл ввод пользовательских типов лишним (я не знаю почему я не сделал так, себе бы я сделал так, это ведь на поверхности; видимо не видел необходимости вообще разделять типы в этой задаче, а может просто лень поборола); так-то оно, конечно, да.
0
04.04.2021, 13:58
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2021, 13:58
Помогаю со студенческими работами здесь

Функции, передача массива в качестве параметра
Приветствую) Собственно, есть простенькое задание с двумерными массивами, оно выполнено: ...

Передача временного массива в качестве параметра функции
Здравствуйте, можно ли как то описать параметр функции, что бы передавать в нее не существующий, а...

Передача функции в качестве параметра в другую функцию
Задание стоит следующее: Написать программу, содержащую две функции. Первая функция, вычисляющая...

Передача функции с двумерным массивов в качестве параметра
Всем доброго времени суток. У меня проблема следующего плана. Есть некая функция void...

Передача функции в качестве параметра другой функции
Доброго времени суток, друзья Необходимо параметром функции передать функцию, количество...

Передача указателя в качестве параметра функции динамически подключаемой библиотеки .so
Собственно возможно ли такое? Ниже мои потуги (пытаюсь передать ссылку на глобальную переменную...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru