15

以下代码使用g++ 7.3.0编译成功,而使用clang++ 6.0.0编译失败(编译标志为-std=c++17 -Wall -Wextra -Werror -pedantic-errors):

auto foo = [](auto, auto... tail) {
    if constexpr (sizeof...(tail) > 0)
    {
        return foo(tail...);
    }
    else
    {
        return 42;
    }
};

int main()
{
}

clang++编译错误信息:

错误:用推导类型 'auto' 声明的变量 'foo' 不能出现在它自己的初始化程序中

return foo(tail...);

在这种情况下,什么行为符合标准?

4

1 回答 1

12

从 C++17 开始,Clang 根据[dcl.spec.auto]/10拒绝这个是正确的。

如果需要具有未推导的占位符类型的实体的类型来确定表达式的类型,则程序是非良构的。

需要类型foo来解决递归调用(findoperator()等)。需要确定闭包类型。由于这里推导了闭包类型……您会看到它的去向。

GCC 可能证明它并非总是不可能绕过它,但通常标准禁止它。

于 2018-05-03T13:43:06.820 回答