Я играю с вариативными c шаблонами и выражениями свертки, в частности, делаю преобразования типов для помещения в параметры функций. Я понимаю, что сделать что-то вроде:
template<T, typename ... Args>
void convertAndEvaluate(const vector<T>& convertibles)
{
size_t i = 0;
evaluate(some_function<Args>(convertibles[i++])...);
}
не сработает, поскольку порядок оценки входных данных функции не указан. Выражения свертки могут давать правильный порядок оценки, однако их результат заключен в круглые скобки и не может использоваться в качестве входных данных функции. Я могу добиться того же результата с index_sequences с помощью другой шаблонной функции, но мне было интересно, есть ли более лаконичный способ с C ++ 17, что-то вроде использования constexpr с расширением пакета.
Пример игрушки:
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
template<typename ... Args>
class Foo {
public:
Foo() {}
void just_print(const std::vector<int>& convertible)
{
size_t i = 0;
((cout << static_cast<Args>(convertible[i++]) << " "), ...);
cout << endl;
}
template<typename T,T... ints>
void expandEvaluate(const std::vector<int>& values, std::integer_sequence<T, ints...> int_seq)
{
eval(static_cast<Args>(values[ints])...);
}
void convert(const std::vector<int>& convertible)
{
expandEvaluate(convertible, std::make_index_sequence<sizeof...(Args)>());
}
void convert_wrong(const std::vector<int>& convertible)
{
size_t i = 0;
eval(static_cast<Args>(convertible[i++])...);
}
void eval(const Args&... values)
{
((cout << values << " "), ...);
cout << endl;
}
};
int main()
{
Foo<double, int, float, int, double> bar;
bar.eval(3, 4, 5, 6, 7);
bar.just_print({3, 4, 5, 6, 7});
bar.convert_wrong({3, 4, 5, 6, 7});
bar.convert({3, 4, 5, 6, 7});
return 0;
}
Вывод:
3 4 5 6 7
3 4 5 6 7
7 6 5 4 3
3 4 5 6 7
Edit: ретроспективно, мое решение с целочисленным расширением требует одновременного расширения двух пакетов параметров, это определено в стандарте?