返回的通用lambda的参数据称是自由函数的阴影参数

Tob*_*ann 12 c++ gcc g++ gcc-warning c++14

编译以下代码

template <typename X, typename F>
auto apply(X x, F f)
{
    return f(x);
}

template <typename Y>
auto add_value(Y y)
{
    return [y](auto x)
    {
        return x + y;
    };
}

int main()
{
    apply(1, add_value(2));
}
Run Code Online (Sandbox Code Playgroud)

用g ++(egv 5.4)给出阴影警告.

$ g++ -Wshadow -Werror -std=c++14 shadow_test.cpp 
shadow_test.cpp: In instantiation of ‘add_value(Y)::<lambda(auto:1)> [with auto:1 = int; Y = int]’:
shadow_test.cpp:4:13:   required from ‘auto apply(X, F) [with X = int; F = add_value(Y) [with Y = int]::<lambda(auto:1)>]’
shadow_test.cpp:18:26:   required from here
shadow_test.cpp:10:22: error: declaration of ‘int x’ shadows a parameter [-Werror=shadow]
     return [y](auto x)
                      ^
shadow_test.cpp:2:14: note: shadowed declaration is here
 auto apply(X x, F f)
              ^
cc1plus: all warnings being treated as errors
Run Code Online (Sandbox Code Playgroud)

我不懂为什么.谁能解释一下?

wal*_*lly 7

一定是个bug.

  • 变量没有被遮蔽,因为它不在lambda的封闭范围内,但它确实产生了正确的结果.
  • VS2015不会发出警告.
  • Clang没有发出任何警告.

这是推测性的,但可能发生的是以下替换(或类似的东西):

#include <iostream>

template <typename X, typename Y>
auto add_value(X x, Y y)
{
    auto f = [y](auto x)
    {
        return x + y;
    };
    return f(x);
}

int main()
{
    std::cout << add_value(1, 2);
}
Run Code Online (Sandbox Code Playgroud)

这个程序确实会在Clang上产生阴影警告,但即使这样它也能产生正确的结果.VS2015仍然不认为这值得警告,但它可能是错误的,因为来自lambda的封闭范围的名称也在lambda的范围内.如果它们没有被捕获,则可以使用它们,但可能不会像这里解释的那样使用.