А подскажите про Variadic functions -- я уже себе весь мозг сломал. Везде эта зараза требует что бы был указан хотя бы один аргумент. Мне нужно, что бы можно было единообразно вызвать функцию от любого (и нулевого) числа однотипных аргументов, а их колчиество задавалось, например, в шаблоне. Как тогда обойтись без va_start?
thambs писал: Везде эта зараза требует что бы был указан хотя бы один аргумент.
Нет, это не так. Вернее, это так только для С. В С++ ты можешь спокойно скомпилить вот такое:
C++ Source Code:
int foo(...) { return 42; }
Цитата:
thambs писал: Как тогда обойтись без va_start?
Необходимость сочетать va_start и шаблоны - признак плохого стиля кодирования. Используй std::initializer_list или variadic templates.
Если всё же есть желание натягивать сову на глобус - могу предложить получать доступ к аргументам напрямую из стека, используя ассемблерные вставки.
__asm в шаблонах гарантированно снесёт мозг любому код-ревьюверу. )
>std::initializer_list или variadic templates
нашёл вот такой http://nerdparadise.com/forum/openmic/5712/ вариант, но как-то через рекурсивный шаблон уродливо. Получается, придётся на каждую функцию завершающий дублёр писать... Это уже haskell какой-то получается.
>ассемблерные вставки
это плохо, хотелось бы чего ни будь в стиле:
thambs писал: это плохо, хотелось бы чего ни будь в стиле
Не факт, что все аргументы будут одного типа. Более того, не факт, что все они одного размера.
Но в принципе std::initializer_list как раз и делает то, что тебе нужно.
>имя уже необязательно
А доступ к ним как получать?
>std::initializer_list
Вызов будет f({arg1, arg2, ...}), эти скобки убрать что бы выглядело как обычная функция.
ну, через ассемблер к примеру по смещению. Или как-нибудь получить указатель на функцию внутри самой себя и посчитать смещение до первого аргумента (+4 байта). Но я не уверен что компилятор такое прожует, да и ни к чему это.
// since initializer lists guarantee sequencing, this can be used to
5
// call a function on each element of a pack, in order:
6
int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... };
7
}
source
Если в функцию не подается аргументов, то можно использовать либо константную проверку (правда она вроде только в C++17)
Ну или можно использовать std::vector
ComradeAndrew
По смыслу получается, что функция принимает аргументы по значению (т.е. копирует их), а потом ещё раз копирует внутрь массива int dummy[]? Можно ли добиться поведения аналогичного передаче по ссылке?
И ещё вопрос -- а можно сделать количество однотипных аргументов параметром шаблона?