gpt4 book ai didi

c++ - 为未定义函数选择正确重载的编译器差异

转载 作者:行者123 更新时间:2023-11-30 05:37:55 24 4
gpt4 key购买 nike

让我们有以下代码:

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

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');
}

它在 MSVC2015 和 ideone's GCC 上表现不同

args... 等于 48, '4', '5' 时,调用 foo。编译器因调用哪个 foo 而异。 MSVC 考虑了在实际调用中定义的重载(之前没有声明),而 GCC 只适用于已经声明的重载。如果我取消注释声明,MSVC 和 GCC 都会打印 1 2 4 3 5 48。如果声明被注释掉,MSVC 打印相同,但 GCC 打印 1 2 3 5 52 48(52 是 4 的 ascii)

根据标准,哪个编译器是正确的?

我有 n4296 草稿,但我在那里找不到答案,该文件对我来说有点不可读...

最佳答案

MSVC 无法实现 two phase name lookup对于标准规定的模板。此编译器错误地将所有名称解析推迟到模板实例化的点。

其他编译器在模板定义 处正确解析非依赖名称。这就是您观察到的差异的原因。在定义点,第二个 foo 模板是不可见的,因此符合规范的编译器无法使用它。但在实例化时,它是可见的并且 MSVC 很高兴地找到了它。

关于c++ - 为未定义函数选择正确重载的编译器差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33062923/

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