gpt4 book ai didi

templates - 将可变参数模板转换为函数调用的线性编译时算法

转载 作者:行者123 更新时间:2023-12-05 01:04:38 28 4
gpt4 key购买 nike

我有一个可变参数模板函数,它接受任意数量的参数。我需要将这些参数转换为顺序重要的函数调用序列。以下方法有效:

#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;
}

但是,上面的代码扩展为传递给 expandVariadic 的参数的二次方数。我可以强制内联 expandVariadic,但这仍然意味着二次编译时间。

是否有线性时间方法来实现上述效果?

(它们必须是函数调用:想象一个生成一系列输出调用的记录器,或者用类型信息填充 vector<> 的东西。)

最佳答案

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接受一系列 lambda 或其他 nullary 可调用对象,并按从左到右的顺序调用它们。这是有效的,因为在 {} 中进行评估的 sink _[] C++11 标准保证行是从左到右的。

我将返回值转换为 void然后用 0 调用逗号运算符在 RHS 上以保证我们得到一个可以转换为 sink 的值。 . (void) cast 处理传入的 lambda 返回一个覆盖 operator, 的对象的极端情况。 .

这种技术的缺点是对 lambda 内部包的支持不如对其他包扩展的支持广泛。我研究过的许多编译器都能够对大多数代码进行参数包扩展,但是当有问题的参数包在 lambda 内部并且扩展在外部时失败了。

关于templates - 将可变参数模板转换为函数调用的线性编译时算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22726752/

28 4 0