Вы не можете использовать ссылки с va_start
в соответствии со стандартом C ++ 18.7 / 3:
Ограничения, которые ISO C накладывает на второй параметр макроса va_start () в заголовке. в настоящем стандарте отличаются. Параметр parmN - это идентификатор Самый правый параметр в списке переменных параметров определения функции (тот, который находится непосредственно перед ...). Если параметр parmN объявлен с функцией, массивом или ссылочным типом либо с несовместимым типом с типом, который возникает при передаче аргумента, для которого нет параметра, поведение неопределенный.
Короткий ответ: нет, так делать нельзя.
ПРИМЕЧАНИЕ: я видел первый ответ, который цитирует стандарт, но я считаю, что стоит показать и мои тесты.
va_start
определяется так:
Visual 6: #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
Visual 8: #define _crt_va_start(ap,v) ( __va_start(&ap, _ADDRESSOF(v), _SLOTSIZEOF(v), \
__alignof(v), _ADDRESSOF(v)) )
С этим кодом:
#include <cstdio>
int main()
{
char c;
char &rc = c;
int i;
int &ri = i;
printf("char ref:%d\n", sizeof(rc));
printf("int ref:%d\n", sizeof(ri));
return 0;
}
вывод
char ref:1
int ref:4
Так как на уровне реализации ссылки передаются на стек аналогично указателям, это представляет проблему, так как размер отличается (это из-за макроса, который вычисляет размер типа, не учитывая, что параметр на самом деле является ссылкой, которая не постоянна, а зависит от фактического размера типа).