Linear compilation algorithm for converting a variational pattern into function calls

I have a variable template function that takes an arbitrary number of arguments. I need to turn these arguments into a sequence of function calls where order matters. The following approach works:

#include <iostream>
#include <typeinfo>
#include <vector>

void printType(const std::type_info& ti) {
    printf("%s\n", ti.name());
}

void expandVariadic() {
}

template<typename First, typename... Rest>
void expandVariadic(const First& first, const Rest&... rest) {
    printType(typeid(First));
    expandVariadic(rest...);
}

int main(int argc, const char* argv[]) {
    expandVariadic(10, "hi", std::cout, std::vector<int>());
    return 0;
}

However, the above code expands to the square number of arguments passed to expandVariadic. I can force embed expandVariadic, but that still means quadratic compile time.

Is there a linear time approach for doing the above?

(They should be functional calls: imagine a log that generates a sequence of output calls or something that populates a vector <> with type information.)

+4
2
struct sink{template<class T>sink(T&&){};};
void run_in_order(){}
template<typename... Fs>
void run_in_order(Fs&&...fs){
  sink _[]={((void)std::forward<Fs>(fs)(),0)...};
  sink{_};// warning elimination
}

:

template<typename... Ts>
void expandVariadic(const Ts&... ts) {
  run_in_order([&]{printType(typeid(ts));}...);
}

run_in_order. run_in_order lambdas . , {} sink _[] ++ 11 .

void, 0 RHS, , , sink. (void) , lambda , operator,.

, lambdas , . , , , , , .

+4

:

#include <iostream>
#include <typeinfo>
#include <vector>

void printType( const std::type_info& ti ) {
    std::cout << ti.name() << '\n';
}

// because cast to void is a non generic way to hide unused variable warning.
template <typename T> void ignore(T&&) {}

template<typename... Ts>
void expandVariadic(Ts&&... ts) {
    // expand by using a initializer list.
    auto il { ( printType( typeid(std::forward<Ts>(ts)) ), 0)... };
    ignore(il);
}

int main(int argc, const char* argv[]) {
    expandVariadic(10, "hi", std::cout, std::vector<int>());
    return 0;
}
+1

Source: https://habr.com/ru/post/1533995/


All Articles