gpt4 book ai didi

c++ - gcc 接受并拒绝带有嵌套泛型 lambda 的此代码,为什么?

转载 作者:行者123 更新时间:2023-12-03 14:20:53 28 4
gpt4 key购买 nike

根据 Godbolt 的 Compiler Explorer(参见 demo),以下代码使用 GCC(10.2 和主干)编译并输出 3628800,但无法使用 Clang(11.0.1 和主干)编译。在这两种情况下,-std=c++17用来。它还可以使用 MSVC 19 进行编译,但不能使用其他编译器进行编译。为什么会这样,谁的行为是正确的?

#include <iostream>

int main()
{
std::cout << [](auto f) { return f(f); }(
[](auto& h) {
return [&h](auto n) {
if (n < 2)
return 1;
else
return n * h(h)(n - 1);
};
})(10) << std::endl;
}


此外,如果我替换 auto n,即使 GCC 和 MSVC 也会拒绝代码与 int n或者如果我用三元运算符( return n < 2 ? 1 : (n * h(h)(n - 1)); )替换 if-else 。

最佳答案

此程序格式错误,无需诊断 ,所以两种实现(实际上,任何实现)都是正确的。违反的规则是 [temp.res.general]/6.4:

a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter


这里的模板是最里面的 operator() :它使用直接包含 operator() 的特化(它是作为模板参数的成员的闭包类型),它具有推导的返回类型。这里的“立即跟随”(仍然)在应该推导出该类型的返回语句中,因此实例化将由于 h(h) 而格式错误。 ,不涉及该模板的模板参数(即 n 的类型)。
GCC 和 MSVC 在最终实例化之前不会对推导的返回类型进行语义检查(使用 int 表示 10),此时返回类型是已知的:它只是最内层 lambda 的适当变体。但是,如果最里面的 lambda 不是通用的,则会进行检查 期间包含 operator() 的实例化,并发生同样的错误。
这种行为差异可以在一个更简单的例子中看到:
auto g();
template<class T> auto f(T x) {return g()-x;}
Clang 在这一点上已经拒绝了,但是 GCC 接受了,也许紧随其后
auto g() {return 1;}
int main() {return f(1);}

关于c++ - gcc 接受并拒绝带有嵌套泛型 lambda 的此代码,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66617181/

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