gpt4 book ai didi

c++ - 可变参数模板在以下情况下如何工作?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:10:18 24 4
gpt4 key购买 nike

http://coliru.stacked-crooked.com/a/5d16c7e740a31a02

#include <iostream>
template<typename T> void P(T x) { std::cout << x; }
void foo(char a) {
P(3);
P(a);
}
template <typename... A>
void foo(int a, A... args) {
foo(args...);
P(a);
}
template <typename... A>
void foo(char a, A... args) {
P(a);
foo(args...);
}
int main()
{
foo('1', '2', 48, '4', '5');
}

//1243548 My result (VS2015)
//12355248 correct result (clang, gcc)

如何生成“正确”的结果?

最佳答案

这里的技巧是 fooint 重载不知道 char 重载,因为它还没有被看到,因此该级别的调用对自身递归:

template <typename... A>
void foo(int a, A... args) { /* only ever calls itself and above*/}

因此调用 foo(48, '4', '5')

将通过对 foo(int a, A...) 的额外调用进行递归,其中 chars 将被解释为 int!

因此您将按预期获得初始 12,但随后您将只打印字符的 ASCII 值,因此您将获得 52 的值'4''5' 的值为 53。 Clang 和 gcc 是正确的;您的 Visual Studio 版本打印了错误的值。 ( I was able to reproduce with VC 19.00.23506 )

这是调用跟踪(instrumented with some help from C++17):

Called foo(char a, A... args) with 1,2,48,4,5
Called P(T) with 1
Called foo(char a, A... args) with 2,48,4,5
Called P(T) with 2
Called foo(int a, A... args) with 48,4,5
Called foo(int a, A... args) with 52,5
Called foo(char a) with 5
Called P(T) with 3
Called P(T) with 5
Called P(T) with 52
Called P(T) with 48

现在,如果我们移动您的代码以便我们转发声明我们的模板(这始终是一个好习惯),您将获得您想要的行为:

template<typename T> 
void P(T x);

template <typename... A>
void foo(int a, A... args);

template <typename... A>
void foo(char a, A... args);

// actual definitions below...

然后你会得到你想要的输出。这是该版本的堆栈跟踪 (demo):

Called foo(char a, A... args) with 1,2,48,4,5
Called P(T) with 1
Called foo(char a, A... args) with 2,48,4,5
Called P(T) with 2
Called foo(int a, A... args) with 48,4,5
Called foo(char a, A... args) with 4,5
Called P(T) with 4
Called foo(char a) with 5
Called P(T) with 3
Called P(T) with 5
Called P(T) with 48

关于c++ - 可变参数模板在以下情况下如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42772365/

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