Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.95/22: Рейтинг темы: голосов - 22, средняя оценка - 4.95
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22

Как указать тип аргумента шаблона для функции?

07.03.2019, 17:50. Показов 5224. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
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
#include <iostream>
#include <windows.h>
#include <vector>
#include <stdexcept>
#include <algorithm>
 
using namespace std;
 
void println()
{
    cout << endl;
}
 
template<typename T>
void print(T source)
{
    cout << source;
}
 
template<typename T>
void println(T source)
{
    print(source);
    println();
}
 
template<typename TIterator>
void print(TIterator begin, TIterator end)
{
    while (begin < end)
    {
        cout << *begin << " ";
        begin++;
    }
}
 
template<typename TIterator>
void println(TIterator begin, TIterator end)
{
    print(begin, end);
    println();
}
 
 
bool predicate(int arg0)
{
    return arg0 % 2 == 0;
}
 
int main(int argc, char** argv)
{
    SetConsoleOutputCP(1251);
    
    vector<int> x;
    for (int i = 0; i < 10; i++)
        x.push_back(i);
    
    println(x.begin(), x.end());
    
    println<vector<int>::iterator, vector<int>::iterator, (*action)(int x)>(count_if(x.begin(), x.end(), predicate));
 
    for_each(x.begin(), x.end(), print);
    
    return 0;
}
Без явного указания компилятор не мог понять какой print я имею ввиду. У меня не получается указать тип print:
C++
1
 (*action)(int x)
Добавлено через 21 минуту
Цель: вывести через println результат count_if.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.03.2019, 17:50
Ответы с готовыми решениями:

Как узнать тип данных шаблона функции?
Я старался делать так: #include&lt;iostream&gt; #include&lt;fstream&gt; #include&lt;conio.h&gt; #include&lt;stdlib.h&gt; #include&lt;string&gt; using namespace...

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

Что может выступать в качестве аргумента функции, если тип параметра указан как std::ostream?
#include &lt;iostream&gt; void func1(std::ostream so); void main() { func1(аргумент); std::cin.get(); } void...

27
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
07.03.2019, 19:09
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Undisputed Посмотреть сообщение
Для for_each требуется конкретная функция а не шаблон.
Выявление типа шаблона в функциях происходит по факту передачи аргументов.
А в момент вызова for_each шаблонной функции еще не переданы аргументы.
Соответственно каким будет тип Т так же неизвестно.
Если явно определить что есть Т - тогда будет работать
Прохладная история, Бро))

А теперь правильный ответ:

Декларация функции имеет вид:
C++
1
2
template <class InputIterator, class Function>
   Function for_each (InputIterator first, InputIterator last, Function fn);
Вот так, через одно место сделали.
Они могли бы вывести сигнатуру Function из типа аргумента InputIterator.
Но они этого не сделали.

Разработчики решили: да ладно, итак сойдёт!

Но из того факта, что в стандартной библиотеке сделали через задницу,
никак не следует, что "выявление типа шаблона в функциях в принципе происходит через задницу".


Соколиный глаз, у вас в коде фигурирует:
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
for_each(x.begin(), x.end(), print<int>); // error
И есть две перегрузки, которые подходят под такое описание:

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
template<typename T>
void print(T source)
И

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
template<typename TIterator>
void print(TIterator begin, TIterator end)
В обоих случаях - это шаблон с одним параметром.
Ну и какая именно имеется ввиду?

Компилятор не телепат.
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
07.03.2019, 19:11
Цитата Сообщение от Undisputed Посмотреть сообщение
Например когда перегружаем родительский метод библиотечного класса
Вернее не перегружаем а переопределяем.

_stanislav,
Наверное уровень выдачи ошибок не на подходящем уровне... должен быть warning
1
Alvin Seville
 Аватар для Соколиный глаз
343 / 273 / 134
Регистрация: 25.07.2014
Сообщений: 4,537
Записей в блоге: 22
07.03.2019, 19:12  [ТС]
eva2326, Вы хотите сказать, что компилятор сначала зырит на количество шаблонных параметров?
0
07.03.2019, 19:13

Не по теме:

Цитата Сообщение от eva2326 Посмотреть сообщение
Прохладная история, Бро))
Проверьте форточку...

0
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
07.03.2019, 19:18
Лучший ответ Сообщение было отмечено Соколиный глаз как решение

Решение

Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Главный вопрос - почему
template<typename TIterator1, typename TIterator2>
void print(TIterator1 begin, TIterator2 end) //
Потому что одна версия с одним параметром, а вторая - с двумя.
Когда вы пишете: print<int>, очевидно жеж,
что имеется ввиду версия с одним параметром,
неоднозначности не возникает.

Добавлено через 1 минуту
Цитата Сообщение от Соколиный глаз Посмотреть сообщение
Вы хотите сказать, что компилятор сначала зырит на количество шаблонных параметров?
А как он по вашему должен догадаться, какую именно версию шаблона функции вы имеете ввиду?
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
07.03.2019, 19:22
Думал, думал над задачей, потом придумал сам себе другую и вот результат - надеюсь будет интересно
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
#include <iostream>
#include <windows.h>
#include <vector>
#include <stdexcept>
#include <algorithm>
#include <type_traits>
#include <numeric>
 
namespace details
{
    template<class T> struct property_
    {
        template <typename T, typename = void>
        struct is_std_container
            : std::false_type {};
 
        template <typename T>
        struct is_std_container<T, std::void_t<decltype(std::declval<T&>().begin()), decltype(std::declval<T&>().end()), typename T::value_type>>
            : std::true_type {};
 
        template<typename T, typename = void>
        struct is_iterator
            : std::false_type {};
 
        template<typename T>
        struct is_iterator<T, typename std::enable_if<!std::is_same<typename std::iterator_traits<T>::value_type, void>::value>::type>
            : std::true_type {};
 
        enum { eINTEGRAL = std::is_integral<T>::value };
        enum { eCONTAINER = is_std_container<T>::value };
        enum { eITERATORS = is_iterator<T>::value };
        enum { eIS_OTHER = !eINTEGRAL && !eCONTAINER && !eITERATORS };
    };
 
    template<class T>
    using for_integer = typename std::enable_if< property_<T>::eINTEGRAL >::type*;
 
    template<class T>
    using for_iterators = typename std::enable_if< property_<T>::eITERATORS  >::type*;
 
    template<class T>
    using for_container = typename std::enable_if< property_<T>::eCONTAINER  >::type*;
 
    template<class T>
    using for_other = typename std::enable_if< property_<T>::eIS_OTHER >::type*;
}
 
template<typename T, details::for_integer<T> = nullptr>
void print(T source)
{
    std::cout << "(int)" << source << std::endl;
}
template<typename T, details::for_other<T> = nullptr>
void print(T source)
{
    std::cout << "(other)" << source << std::endl;
}
 
template<typename It, details::for_iterators<It> = nullptr>
void print(It beg, It end)
{
    std::cout << "(iter)";
    while (beg < end)
    {
        std::cout << *beg << " ";
        beg++;
    }
    std::cout << std::endl;
}
 
template<typename Cont, details::for_container<Cont> = nullptr>
void print(Cont& cont)
{
    std::cout << "(cont)";
    auto beg = std::begin(cont);
    auto end = std::end(cont);
    while (beg< end)
    {
        std::cout << *beg << " ";
        beg++;
    }
    std::cout << std::endl;
}
 
 
int main()
{
    std::vector<int> x;
    x.resize(10);
    std::iota(std::begin(x), std::end(x), 0);
 
    print(1);
    print(std::begin(x), std::end(x));
    print(x);
    print(0.5f);
 
    return 0;
}
1
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
07.03.2019, 19:43
Цитата Сообщение от eva2326 Посмотреть сообщение
Потому что одна версия с одним параметром, а вторая - с двумя.
Главное не забудьте объяснить почему для кода
C++
1
2
3
4
5
6
7
8
9
10
11
template<typename Func>
void func(Func callback)
{
    callback(100);
}
 
template<typename T>
void printCallback(T data)
{
    std::cout << data;
}
Вызов
C++
1
func(printCallback);
не компилируется
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
07.03.2019, 20:35
Цитата Сообщение от _stanislav Посмотреть сообщение
у меня в студии о неиспользуемых параметрах вообще тишина, и я считаю что это правильно.
Просто недостаточно высокий уровень предупреждений. Поставь /W4 и все будет. GCC\Clang тоже не при любом уровне такое выдают.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.03.2019, 20:35

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

Указать тип переменной в шаблонной функции
Доброго времени суток, форумчане! Есть переменная. Есть шаблонная функция. Как в качестве параметра шаблона мне указать тип данных, к...

Как правильно указать в Sql запросе логический тип данных и тип "Дата время"?
Как правильно указывать в sql запросе логический тип и тип &quot;дата время&quot;? К примеру, запрос следующего вида: INSERT INTO График VALUES...

Как указать смещение в буфере для функции BlockRead?
var Buf: arrayof byte; F: file of Byte; ... Count:= 16; BlockRead(F, Buf, Count); Как указать смещение в буфере? То есть...

Как исправить ошибку в XE7 при указании типа аргумента для функции?
Добрый день! Раньше писал сайты на php и Yii, решил освоить с++ и компоненты Среды разработки Embarcadero RAD STUDIO XE7....


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

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Новые блоги и статьи
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru