gpt4 book ai didi

c++ - 将可变参数模板粘合到可变参数函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:48:13 31 4
gpt4 key购买 nike

为了绕过 GCC 在 libc++ 中未实现的始终内联的可变参数函数,我认为我可以将可变参数函数(如 snprintf,更准确地说,*_l 变体)包装在可变参数模板中以实现类似的效果。实例化将填充可变参数函数的可变参数,从而使函数可以很好地内联。问题是,我对编写可变参数模板一无所知,而且我当然不知道如何将模板参数转换为单独的参数。

我要替换的代码的形式是:

int __sprintf_l(char *__s, locale_t __l, const char *__format, ...) {
va_list __va;
va_start(__va, __format);
int __res = vsprintf_l(__s, __l, __format, __va);
va_end(__va);
return __res;
}

我想将 is 替换为以下形式:

template<typename... Args>
int __sprintf_l(char *__s, locale_t __l, const char *__format, Args... args) {
int __res = vsprintf_l(__s, __l, __format, args...);
return __res;
}

这不起作用,因为扩展的 args... 无法转换为 typeva_list {aka char*} .如果没有办法,我将不得不相信 Howard 并实现一个和两个参数的始终内联模板,这将有效地使所需代码量翻倍。

编辑:也许将 args 中的 std::tuple 转换成 va_list 的方法在这里可行吗?

最佳答案

我认为您提出的问题令人困惑,所以让我重申一下。

您想使用可变参数模板编写一个模拟内联可变参数函数的函数。

这是不可能的。 va_args 通常作为堆栈上第一个参数的 void* 实现(请注意,出于这个原因,可变参数函数需要至少有一个非可变参数)。

您需要操纵调用堆栈以在正确的位置获取参数。现在可能是可变参数模板函数的参数在堆栈上与 va_args 需要它们的相同位置,但这需要模板函数不被内联。

我强烈怀疑始终内联可变参数函数未实现的原因是因为 va_args 的实现假设标准堆栈布局。对于内联该函数的编译器,它需要分配堆栈空间并将参数复制到位。它唯一会保存的是实际的 jmpret 指令。

这可以做到,但是内联的一半好处消失了。此外,编译器必须将参数传递代码(即编译器代码)提升到更通用的位置,以便与常规函数调用一起使用,作为可变参数函数的强制内联。换句话说,它使控制流显着复杂化,但 yield 很小甚至没有 yield 。

关于c++ - 将可变参数模板粘合到可变参数函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7545309/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com