Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175

Вариативные шаблоны

20.03.2020, 15:48. Показов 4267. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Разбираюсь с вариативными шаблонами, есть ли какой-нибудь способ не изменяя функцию fSecond, через неё пропустить некоторое количество параметров функции fFirst? Если да, то как?

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
#include <iostream>
#include <string>
#include <typeindex>
#include <type_traits>
 
class One{};
 
class Two : public One {};
 
class Three : public One {};
 
template<typename ... Args>
void fFirst() {
    fSecond<Args ...>();        //Тут ошибка
}
 
template<typename T>
void fSecond() {
    std::cout << typeid(T).name() << "\n";
}
 
int main()
{
    fFirst<One, Two, Three>();
 
    system("pause");
    return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.03.2020, 15:48
Ответы с готовыми решениями:

Вариативные шаблоны
почему не работает template &lt;typename E, typename... Types&gt; void print(const E Arg, const Types&amp;... args) { cout &lt;&lt; Arg &lt;&lt;...

Шаблонные параметры шаблонов и вариативные шаблоны
Привет, как узнать, что находится в Args? Мой вариант не робит почему то... #include &lt;iostream&gt; #include &lt;deque&gt; ...

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если есть, то в чём? И где (в каких...

20
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.03.2020, 16:06
Лучший ответ Сообщение было отмечено Battary как решение

Решение

Цитата Сообщение от Battary Посмотреть сообщение
не изменяя функцию fSecond, через неё пропустить некоторое количество параметров функции fFirst?
https://rextester.com/DHOD69249

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
#include <iostream>
#include <string>
#include <typeindex>
#include <type_traits>
#include <tuple>
 
class One{};
 
class Two : public One {};
 
class Three : public One {};
 
template<typename T>
void fSecond() { std::cout << typeid(T).name() << "\n"; }
 
namespace detail 
{
    template<typename Tuple, size_t... Index>
    void typeForeachImpl(const ::std::index_sequence<Index...>)
    {
        const auto unused = 
        { 
            true, 
            ( 
                fSecond< ::std::tuple_element_t<Index, Tuple> >(),
                void(), 
                true 
            ) ... 
        };
        (void) unused;
    }
 
}//namespace detail 
 
template<typename ... Args>
void fFirst()
{
    using tuple = ::std::tuple<Args...>;
    using tuple_size = ::std::tuple_size<tuple>;
    enum { size = tuple_size::value };
    using index_t = ::std::make_index_sequence<size>;
 
    ::detail::typeForeachImpl<tuple>(index_t());
}
 
int main()
{
    fFirst<One, Two, Three>();
}
но я бы на твоём месте так не делал.
есть другой, более универсальный способ.
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.03.2020, 16:15
если чуть попроще для понимания:
Кликните здесь для просмотра всего текста

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>
#include <string>
#include <typeindex>
#include <type_traits>
 
class One {};
 
class Two : public One {};
 
class Three : public One {};
 
template<typename T>
void fSecond() {
    std::cout << typeid(T).name() << "\n";
}
 
template<typename ... Args>
void fFirst(std::tuple<Args...> = {}) {
    (fSecond<Args>(), ...);
}
 
 
int main()
{
    fFirst<One, Two, Three>();
 
    system("pause");
    return 0;
}
2
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 16:24  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
если чуть попроще для понимания:
Кликните здесь для просмотра всего текста

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>
#include <string>
#include <typeindex>
#include <type_traits>
 
class One {};
 
class Two : public One {};
 
class Three : public One {};
 
template<typename T>
void fSecond() {
    std::cout << typeid(T).name() << "\n";
}
 
template<typename ... Args>
void fFirst(std::tuple<Args...> = {}) {
    (fSecond<Args>(), ...);
}
 
 
int main()
{
    fFirst<One, Two, Three>();
 
    system("pause");
    return 0;
}
Как понимаю, это и не должно было скомпилироваться, а только упрощение кода для понимания?

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
https://rextester.com/DHOD69249
но я бы на твоём месте так не делал.
есть другой, более универсальный способ.
А можно название этого способа или ссылку, где почитать про него?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.03.2020, 16:32
Цитата Сообщение от Battary Посмотреть сообщение
А можно название этого способа или ссылку, где почитать про него?
не знаю как он называется.
я до этого способа сам дошел.
назвал его "typeForeach" - для перебора типов
и "tupleForeach" - для перебора значений разных типов.
причем задолго до того, как в стандарт завезли std::index_sequence.
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.03.2020, 16:35
Цитата Сообщение от Battary Посмотреть сообщение
Как понимаю, это и не должно было скомпилироваться, а только упрощение кода для понимания?
https://wandbox.org/#wandbox-r... ode-body-3
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 17:03  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
Cтранно, vs не компилирует, оболочка linux тоже:
Кликните здесь для просмотра всего текста
TestC++2.cpp: In function ‘void fFirst(std::tuple<_Tps ...>)’:
TestC++2.cpp:16:3: error: ‘fSecond’ was not declared in this scope
(fSecond<Args>(), ...);
^~~~~~~
TestC++2.cpp:16:15: error: expected primary-expression before ‘>’ token
(fSecond<Args>(), ...);
^
TestC++2.cpp:16:17: error: expected primary-expression before ‘)’ token
(fSecond<Args>(), ...);
^
TestC++2.cpp:16:20: error: operand of fold expression has no unexpanded parameter packs
(fSecond<Args>(), ...);
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
20.03.2020, 17:08
Цитата Сообщение от Battary Посмотреть сообщение
Cтранно, vs не компилирует, оболочка linux тоже:
нужна поддержка с++17

Добавлено через 3 минуты
ну или так распаковывать
C++
1
int arr[] ={(fSecond<Args>(), 0)...};
1
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 17:24  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
нужна поддержка с++17

Добавлено через 3 минуты
ну или так распаковывать
C++
1
int arr[] ={(fSecond<Args>(), 0)...};
Cпасибо, все заработало, но только на черновике c++latest. А вариант для с++14 или с++11 есть?

C++
1
2
3
4
template<typename ... Args>
void fFirst() {
    int arr[] = { (fSecond<Args>(), 0)... };
}
0
20.03.2020, 17:38

Не по теме:

Цитата Сообщение от Battary Посмотреть сообщение
А вариант для с++14 или с++11 есть?
gcc 4.7.3 c++11 например компилирует...
Ну а вариант hoggy, как у вас компилировался?

0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 17:45  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение

Не по теме:


gcc 4.7.3 c++11 например компилирует...
Ну а вариант hoggy, как у вас компилировался?

Не по теме:

Там все хорошо компилируется, на ++14 точно.

0
20.03.2020, 17:58

Не по теме:

Цитата Сообщение от Battary Посмотреть сообщение
на ++14 точно
VS17 11 и 14 стандарт собирает без вопросов

0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 18:07  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение

Не по теме:


VS17 11 и 14 стандарт собирает без вопросов

Не по теме:

Надо будет попробовать на других машинах, но позже, видимо зависит от компилятора. Надо разобраться в примере hoggy , уж больно тяжело написано для моего уровня, на это уйдет время.

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,217
20.03.2020, 18:08
Цитата Сообщение от Battary Посмотреть сообщение
не изменяя функцию fSecond, через неё пропустить некоторое количество параметров функции fFirst?
Используем обычный fold-expression в fFirst

C++
1
2
3
4
5
template<typename ... Args>
void fFirst() 
{
  (fSecond<Args>(), ...);
}
Готово.

Однако необъявленное имя функции fSecond в функции fFirst не является зависимым именем, по каковой причине компилироваться это не будет. Либо перенесите определение fSecond наверх, либо сделайте предварительное объявление fSecond наверху.
2
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.03.2020, 18:10
Цитата Сообщение от Battary Посмотреть сообщение
А вариант для с++14 или с++11 есть?
такой код должен компилироваться:

https://rextester.com/ZGHV14041

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <typeinfo>
 
class One{};
 
class Two : public One {};
 
class Three : public One {};
 
template<typename T>
void fSecond() { std::cout << typeid(T).name() << "\n"; }
 
template<typename ... Args>
void fFirst()
{
    const auto unused = { true, (fSecond<Args>(), void(), true)... };
    (void) unused;    
}
 
int main()
{
    fFirst<One, Two, Three>();
}
на что здесь нужно обратить внимание?
unused - это на самом деле std::initializer_list

вот такая хитрая комбинация с использованием true и void()
C++
1
{ true, (fSecond<Args>(), void(), true)... }
нужна, что бы шаблон не сломался на типах,
для которых перегружен оператор запятая

более простая комбинация:
Цитата Сообщение от zayats80888 Посмотреть сообщение
{(fSecond<Args>(), 0)...};
может сломаться.
1
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
20.03.2020, 18:13
Цитата Сообщение от zayats80888 Посмотреть сообщение
C++
1
2
3
4
5
template<typename ... Args>
void fFirst(std::tuple<Args...> = {})
{
    (fSecond<Args>(), ...);
}
В строке 2, как я понял, указан безымянный параметр со значением по умолчанию. Правильно?

А вот конструкцию в строке 4 я что-то не понял. Что это, Уотсон?
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
20.03.2020, 18:17  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
[CPP]
template<typename ... Args>
void fFirst()
{
const auto unused = { true, (fSecond<Args>(), void(), true)... };
(void) unused;
}
Да, спасибо, все понятно, но зачем потом преобразовывать в общий указатель?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.03.2020, 18:18
Цитата Сообщение от L0M Посмотреть сообщение
А вот конструкцию в строке 4 я что-то не понял. Что это, Уотсон?

https://en.cppreference.com/w/cpp/language/fold
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,217
20.03.2020, 18:20
Лучший ответ Сообщение было отмечено Battary как решение

Решение

Цитата Сообщение от Battary Посмотреть сообщение
А вариант для с++14 или с++11 есть?
Для С++11 решения (т.е. без fold expressions) не нужно городить никакой огород, а можно сделать обычный вариабельный шаблон функции с рекурсией

C++
1
2
3
4
5
6
7
8
9
10
template<typename T>
void fFirst() {
    fSecond<T>();
}
 
template<typename T, typename ... Args>
typename std::enable_if<(sizeof...(Args) > 0)>::type fFirst() {
    fSecond<T>();
    fFirst<Args ...>();
}
Опять же, шаблон функции fSecond должен быть объявлен выше.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
20.03.2020, 18:24
Цитата Сообщение от Battary Посмотреть сообщение
о зачем потом преобразовывать в общий указатель?
Цитата Сообщение от Battary Посмотреть сообщение
(void) unused;
здесь нет ни указателя, ни преобразования в указатель.

просто значение переменной unused нигде не используется.
и это смущает компилятор:
Code
1
2
source_file.cpp:16:16: warning: unused variable ‘unused’ [-Wunused-variable]
     const auto unused = { true, (fSecond<Args>(), void(), true)... };
вот что бы он не генерировал ворнинг, и используется конструкция вида:
C++
1
(void) unused;   // над переменной выполняется действие: "ничего не деланье"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.03.2020, 18:24
Помогаю со студенческими работами здесь

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не плодить много тем, корни у которых одни, решил создать эту...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1) количество элементов массива, равных 0; 2) сумму элементов...

Вариативные макросы
Я пытаюсь реализовать вариативный макрос, объявляю прототип функции realdprintf. Компилятор gcc version 7.4.0 (Ubuntu...

Модуль CRT, Вариативные поля, файлы
Нужна помощь осталась 3 задачи и я не знаю как решить (Болел долго) Помогите ПЛЗ 1. Представить решение любой задачи, проиллюстрировав...

Хранить шаблоны документов в базе и выводить данные в эти шаблоны
Доброго времени суток. Интересует вопрос: мне необходимо формировать вордовские документы по шаблону. У меня создан шаблон документа...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru