§ 5. Вариативные шаблоны

Задания

  1. Напишите функцию message, которая работает аналогично функции printf. Первый аргумент функции — поток, куда будут выводится символы. Второй аргумент функции — шаблон строки, которая отобразится на экране, в котором символом % обозначены места вставки объектов. Остальные аргументы функции — это объекты, которые нужно вставить на место %. Функция при вызове выводит сообщение на стандартный вывод. Например,
    message(std::cout, "% + % = %", 'a', 2, 3.0)
    
    выведет на экран a + 2 = 3.
    • Функция должна быть реализована с помощью шаблона с произвольным количеством аргументов.
    • Напишите модульный тест, в котором проверяется корректность работы функции при несовпадении количества аргументов и количества %. Для сравнения актуального вывода с ожидаемым удобно использовать поток std::stringstream, который осуществляет вывод в строку.
    • В этом задании запрещено использовать оператор "запятая". См. пример в конце.
  2. Напишите функцию cat, которая соединяет произвольное количество массивов в один большой массив. Функция должна принимать произвольное количество аргументов и возвращать объект типа std::array (это один из новых классов стандартной библиотеки C++, который представляет собой статический массив заданного размера). Пример вызова функции:
    std::array<float,3> vec1{1.0f,2.0f,3.0f};
    std::array<float,3> vec2{4.0f,5.0f,6.0f};
    std::array<float,6> r = cat(vec1, vec2); // 1 2 3 4 5 6
    
    • Функция должна быть реализована с помощью шаблона с произвольным количеством аргументов в предположении, что все аргументы имеют тип std::array<T,N> (T и N одинаковы для всех аргументов функции).
    • Напишите модульный тест для проверки корректности работы функции.
    • Для выполнения задания вам может пригодиться оператор sizeof....
    • В этом задании запрещено использовать оператор "запятая". См. пример в конце.
  3. Напишите функцию tie, которая работает также как std::tie, но для массивов, имеющих тип std::array<T,N> (реализовывать аналог std::ignore не нужно). Функция возвращает объект типа Tie (название произвольное), у которого переопределен оператор присваивания:

    template <class T, int N, int M>
    struct Tie {
        void operator=(const std::array<T,N*M>& rhs);
    };
    
    • Функция должна быть реализована с помощью шаблона с произвольным количеством аргументов в предположении, что все аргументы имеют тип std::array<T,N> (T и N одинаковы для всех аргументов функции).
    • Напишите модульный тест для проверки корректности работы функции.
    • В этом задании запрещено использовать оператор "запятая". См. пример в конце.
    Пример вызова функции:
    std::array<float,6> r{1.0f,2.0f,3.0f,4.0f,5.0f,6.0f};
    std::array<float,3> vec1, vec2;
    tie(vec1, vec2) = r; // (1 2 3) (4 5 6)
    
Во всех заданиях запрещено использовать оператор "запятая", как в следующем примере.
int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... };