Пространства имён
Варианты
Действия

va_arg

Материал из cppreference.com
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
 
<tbody> </tbody>
Определено в заголовочном файле <cstdarg>
T va_arg( va_list ap, T );

Макрос va_arg раскрывается в выражение типа T, которое представляет собой следующий аргумент из va_list ap.

До вызова va_arg ap должен быть инициализирован с помощью вызова va_start или va_copy, при этом без промежуточного вызова va_end. Каждый вызов макроса va_arg изменяет ap так, чтобы он указывал на следующий переменный аргумент.

Если тип следующего аргумента в ap (после продвижения) не совместим с T, то поведение будет не определено, исключая следующие случаи:

  • один из типов является знаковым целочисленным, а другой тип соответствующим ему беззнаковым целочисленным, а их значение представимо в обоих типах; или
  • один из типов является указателем на void, а другой тип указателем на символьный тип (char, signed char или unsigned char).

Параметры

ap экземпляр типа va_list
T тип следующего параметра в ap

Раскрывается как

следующий переменный параметр в ap

Пример

#include <cstdarg>
#include <cstdio>
#include <iostream>

void print_variance(std::size_t count, const char* fmt, ...)
{
    double sum = 0;
    double sum_sq = 0;
    std::va_list args;
    va_start(args, fmt);
    for (std::size_t i = count; i--;)
    {
        double num = va_arg(args, double);
        sum += num;
        sum_sq += num*num;
    }
    va_end(args);
    std::printf(fmt, sum_sq / count - (sum / count) * (sum / count));
}

void nano_printf(const char* fmt, ...)
{
    std::va_list args;
    va_start(args, fmt);

    for (const char* p = fmt; *p != '\0'; ++p)
    {
        switch(*p)
        {
        case '%':
            switch(*++p) // читает символ формата
            {
            case 'i': std::cout << va_arg(args, int); continue;
            case 'f': std::cout << va_arg(args, double); continue;
            case 's': std::cout << va_arg(args, const char*); continue;
            case 'c': std::cout << static_cast<char>(va_arg(args, int)); continue;
            case '%': std::cout << '%'; continue;
            /* ...другие варианты... */
            }
            break; // ошибка формата...
        case '\n': std::cout << "\n"; continue;
        case '\t': std::cout << "\t"; continue;
        /* ...другие варианты... */
        }
        std::cout << *p;
    }

    va_end(args);
}

int main()
{
    print_variance(4, "%f\n", 25.0, 27.3, 26.9, 25.7);
    nano_printf("Аргументы: %i%% %c%f %s\n", 42, '#', 3.14, "C++");
}

Вывод:

0.846875
Аргументы: 42% #3.14 C++

Смотрите также

разрешает доступ к аргументам функции с переменным числом аргументов
(функция-макрос) [править]
(C++11)
делает копию аргументов функции с переменным числом аргументов
(функция-макрос) [править]
завершает обход аргументов функции с переменным числом аргументов
(функция-макрос) [править]