Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
 Аватар для Defake
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191

Variadic templates, якобы provided 0 argumnets

17.12.2015, 06:49. Показов 1350. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть кто онлайн? Проблема в вариадик темплейтсах с компилятором. Не пропускает следующий код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template<typename... Args>
    void AddPoint(int point, const Args&... args) {
        /* лялляля
         */
 
        if (sizeof...(args))
            AddEdges(point, args...);
    }
 
 
 
    template<typename... Args>
    void AddEdges(int point, int connectedPoint, const Args&... args) {
        /* лялляля
         */
 
        if (sizeof...(args)) 
            AddEdges(point, args...);
    }
 
//где-то далеко в мейне:
graph.AddPoint(1, 2, 4, 5);


По сути, я точно знаю, что код выполнится правильно в рантайме. Но компилятор упорно не хочет пропускать вызов функции и пишет типа
void Graph::AddEdges(int,int,const Args &...)': expects 2 arguments - 0 provided
В рантайме-то будет выполняться проверка на sizeof и функция, когда 0 агрументов, вызываться не будет. Но он не хочет пропускать даже такое:

C++
1
2
if (false) 
            AddEdges(point, args...);
Всё равно ругается, что функция дескать будет вызвана с нулем аргументов.

Как этот паттерн юзать правильно, подскажите пожалуйста?

Добавлено через 1 час 50 минут
Хмм... Ну я добавил такой трикс вниз:

C++
1
2
3
    void AddEdges(int a) {
        cout << "fuuuuuuuuuuu";
    }
И всё заработало. Но чёёёт мне подсказывает, что это ужасный костыль. Нинада так. Есть что-то более правильное? Или только так с компилятором воевать?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.12.2015, 06:49
Ответы с готовыми решениями:

Variadic Templates - как обращаться к аргументам variadic-функции?
Всем привет! Наверное, рано мне ещё с моими скудными знаниями в это лезть, но, изучив шаблоны и вариадик-функции, я, естественно, горю...

Variadic Templates
проблема только в переводе на русский, обычно это &quot;Шаблоны с переменным числом аргументов&quot; но такое длинное выражение долго не...

Variadic templates
1. как можно сделать чтобы передавались ссылки на переменные? (с variadic templates) 2. как вообще обращаться к переменным объявленным...

9
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.12.2015, 09:46
Лучший ответ Сообщение было отмечено Defake как решение

Решение

Цитата Сообщение от Defake Посмотреть сообщение
Или только так с компилятором воевать?
Ненадо.
Фундаментальную вещь не понимаешь. Все ветки if должны быть синтаксически корректны. sizeof...(args) выполняется на этапе компиляции. Но тело if должно быть вычислимо с учетом того, что написано. Т.е. ветвление будет на этапе исполнения, а на этапе компиляции все ветки if должны быть корректны. В твоем примере нет функции AddEdges c одним аргументом, поэтому он справедливо ругается.
В твоем случае получается следующее:
C++
1
2
if (0) // sizeof...(args) == 0 
    AddEdges(point); // args... - пустой
Так что решение с пустой функцией - можно рассматривать совершенно свободно. Это не костыль, а один из справедливых вариантов прервать шаблонную рекурсию.

Однако, обычно делают как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void AddEdges(int point, int connectedPoint) 
{
    /* лялляля
     */
}
 
template<typename... Args>
void AddEdges(int point, int connectedPoint, const Args&... args) 
{
    /* лялляля
     */
    AddEdges(point, args...);
}
Добавлено через 7 минут
Кстати, вот некоторые предложения, которые позволили бы написать этот код в императивном стиле, как ты и хотел:
http://www.open-std.org/jtc1/s... /n3329.pdf.
http://www.open-std.org/jtc1/s... /n3613.pdf
Но это пока на этапе рассмотрения.

Добавлено через 5 минут
Может быть еще интересно вот это решение: http://baptiste-wicht.com/post... 11c14.html
2
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
17.12.2015, 10:07
delete
0
 Аватар для Defake
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
17.12.2015, 12:53  [ТС]
DrOffset, хм, даже если ветка никогда не выполнится (не думаю, что компилятор этого может не видеть. Не помню как в VS, а в qt точно пишет, мол ветка иф не юзается, а переменная не используется), то она всё равно должна быть корректна? Странно.

Ну и да, я просто не видел такого решения (с пустой функцией) в реализациях variadic templates. Везде приводится решение только такое, как я описал в шапке. То есть когда заканчивается набор агрументов в args..., то функция перестает вызываться. Я еще помню удивлялся этому, дескать вот какой компилятор умный, что сам догадывается, что функцию вызывать уже не надо...

И я даже уверен, что сначала, когда я реализовал такой подход, у меня код скомпилировался. А вот потом что я делал.. Убей - не помню =D
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.12.2015, 14:18
Цитата Сообщение от Defake Посмотреть сообщение
Странно.
Это не странно.
Код должен быть корректен в соответствии с правилами языка. Все ветки обрабатываются транслятором, правила для которого диктуются стандартом языка. Достижимость отдельных веток может быть проверена компилятором на этом этапе, но диагностика выдается только в качестве предупреждений. Однако проверка достижимости - это не тоже самое, что отбрасывание синтаксических правил. Это обсусловлено в том числе и историческими причинами, т.к. compile-time вычисления гораздо моложе, чем яык С, от которого С++ унаследовал очень многое. Поэтому единственный разумный вариант - это введение новой конструкции (или нового контекста) специально для compile-time вычислений. Примеры выше я приводил.

Цитата Сообщение от Defake Посмотреть сообщение
Везде приводится решение только такое, как я описал в шапке.
Везде - это где? Такого (как в шапке) просто не может быть. Нельзя обычным if`ом который имеет runtime природу (хоть и зачастую оптимизируется в ноль) проверять статическую информацию о типе функции и делать выводы о компилируемости или некомпилируемости какого-то участка кода. Это совершенно дико в текущих правилах языка.

Обычно используют либо перегрузку, задавая терминальные состояния перегруженными функциями, либо специализацию классов/функций, - классический пример: вычисление факториала в compile-time. Либо используется принцип SFINAE (неверная подстановка не является ошибкой), однако специфичность явления не позволяет так просто распространить его на все ситуации.

Цитата Сообщение от Defake Посмотреть сообщение
И я даже уверен, что сначала, когда я реализовал такой подход, у меня код скомпилировался.
Я понял, ты из тех людей, что любят спорить, что белое - это черное?

Добавлено через 30 минут
Причем стоит понимать, что до тех пор, пока нет инстацирования шаблона, код будет компилироваться в том виде, в котором он написан в шапке. Но это общий вид, кодогенерации не будет, а компилятор обязан проверять только разрешимые в этом общем контексте ситуации. Остальные будут проверены при инстанцировании. Причем компилятор VS не делает этого, поэтому до момента инстацирования даже такой код для него будет "корректным".
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
// cp1251 в VS
template <typename ...T>
void AddEdges(T const & ...args)
{
     я ваш дом-труба шатал!    
}


Собственно, пруф.
Тот же код, но другом компиляторе: CLang: http://rextester.com/MRN43530

Не по теме:

Тексты с кириллицей для VS (cl) на сайте не работают из-за UTF-8, в VS с кодировкой cp1251 для исходника будет жить и код из спойлера.

2
 Аватар для Defake
5 / 5 / 0
Регистрация: 24.08.2011
Сообщений: 191
17.12.2015, 19:54  [ТС]
Везде - это где? Такого (как в шапке) просто не может быть. Нельзя обычным if`ом который имеет runtime природу...
Раньше смотрел вариадик темплейты - там такое было. Но там я не особо их понял. В этот раз серьезнее взялся - снова нашел похожие примеры. Да, там без if-ов. Это уже мои изыски)

В тех примерах было примерно так:

C++
1
2
3
4
5
6
7
8
9
template<typename ...Args>
void foo(Args... arg) {
     bar(arg...);
}
 
template<typename... Args>
void bar(int a, Args... arg) {
     bar(arg);
}
Я же писал:

Я еще помню удивлялся этому, дескать вот какой компилятор умный, что сам догадывается, что функцию вызывать уже не надо...
Воот... Сейчас правда я такие примеры не могу найти =D Видать, мозг воспринимает только ту информацию, которую может воспринять. Особенно когда не спишь 2е сутки) Либо я на примеры фейловые нарывался. Просто именно такой вызов достаточно сложно было найти в инете. Там либо слишком простые вещи (засовывание args... в printf) либо слишком сложные, которые я не понимал, да и не нужны они пока что.

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

В общем, тема, думаю, себя исчерпала, а я уже пустился в лирический оффтоп. Буду теперь юзать этакие "заглушки", прочитаю про статик ифы. В общем, спасибо =)
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
17.12.2015, 20:17
Цитата Сообщение от DrOffset Посмотреть сообщение
Примеры выше я приводил.

Не по теме:

реально, static if хотят узаконить?!

неужели старина Страуструп все таки сдался?

0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.12.2015, 20:58
Цитата Сообщение от Defake Посмотреть сообщение
было примерно так
Ну это тоже самое, что я тебе написал в первом ответе.
И if`а тут нет, о чем и говорилось.
Ладно, я думаю теперь все понятно.

Добавлено через 34 секунды

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
реально, static if хотят узаконить?!
Хотят или нет, я не особо в курсе. Но предложение есть :)

0
17.12.2015, 21:06

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Хотят или нет, я не особо в курсе. Но предложение есть
так предложение ж вроде ещё 100 лет назад уже было...
только Страуструп в бутылку полез:
нехай, говорит, делать из плюсов эти ваши недохаскели

вот так и живем... SFINAE, специализации.. :-[

0
17.12.2015, 21:34

Не по теме:

Цитата Сообщение от hoggy Посмотреть сообщение
только Страуструп в бутылку полез:
нехай, говорит, делать из плюсов эти ваши недохаскели
Я как-то упустил этот момент, может быть. Но по моим ссылкам - совсем недавно было, 2013 год.

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
17.12.2015, 21:34
Помогаю со студенческими работами здесь

Variadic templates
как можно сделать чтобы функция принимала бесконечное количество объектов std::string? (только их) я пробовал вот так: template&lt;const...

Variadic templates
А как бы так исхитриться, чтобы шаблонная функция, использующая Variadic templates узнала размер передаваемых ей параметров с тем, чтобы,...

Variadic templates
typedef function&lt;double(double ...)&gt; fun; inline int sum() { return 0; } template &lt;typename ... Types&gt; double sum(double...

Result_of + variadic templates
Как здесь можно вывести возвращаемый тип функторов? res_t должен получиться типом которым они параметризуются.template &lt;typename ......

Variadic templates fail
Здравствуйте. У меня проблема, нужно реализовать в проекте функционал, который будет использовать шаблоны с переменным количеством...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru