Страницы

Поиск по вопросам

суббота, 20 октября 2018 г.

Непонятный код с variadic templates

Есть код, который, используя variadic templates, печатает любое количество входных аргументов в поток:
template void print(Args&& ...args) { char compile_time_buffer[sizeof...(Args)] = { ((std::cout << args <<" "), 0)... }; std::cout<< "
"; }
Совершенно не могу понять, чем инициализируется массив compile_time_buffer. Что скрывается за синтаксисом ((std::cout << args <<" "), 0)? И почему массив char, а в поток корректно выводятся объекты любого типа?


Ответ

В этом выражении
((std::cout << args <<" "), 0)...
используется оператор запятая. Значением выражения является второй операнд после запятой, то есть 0. В результате символьный массив инициализируется нулями. При этом имеется побочный эффект вычисления первого операнда оператора запятая в виде вывода в поток переданных в функцию аргументов.
Чтобы было более наглядно, то просто замените 0, например, на символ 'A'. Ниже показана демонстрационная программа.
#include
template void print( Args && ...args ) { char compile_time_buffer[sizeof...(Args)] = { ( (std::cout << args <<" "), 'A' )... };
std::cout.write( compile_time_buffer, sizeof...(Args) ); }
int main() { print( 1, 2, 3 );
return 0; }
Ее вывод на консоль следующий
1 2 3 AAA
Можно сделать эту программу более интересной. Например,
#include
template void print( Args && ...args ) { char c = 'A'; char compile_time_buffer[sizeof...(Args) + 1] = { ( std::cout << args <<" ", c++ )... };
std::cout << compile_time_buffer << std::endl; }
int main() { print( 1, 2, 3 );
return 0; }
Ее вывод на консоль следующий
1 2 3 ABC
Вот еще один простой пример использования оператора запятая при инициализации переменной
int x = ( std::cout << "Инициализация x. x = ", 10 ); std::cout << x << std::endl;
На консоль будет выведено
Инициализация x. x = 10

Комментариев нет:

Отправить комментарий