2016-12-18 16 views
11

Compiling следующего кодаПараметра возвращаемой родовой лямбды предположительно тень параметра свободной функции

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

с г ++ (например, ст. 5.4) дает shadow warnings.

$ 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 

Я не понимаю, почему. Может кто-нибудь объяснить?

ответ

6

Должно быть, ошибка.

  • Переменная не затеняется, поскольку она не находится в охватывающей области лямбда, однако она делает produce the correct result.
  • 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); 
} 

Эта программа does produce a shadow warning on Clang, но даже тогда она производит правильный результат. VS2015 по-прежнему не считает это достойным предупреждения, но, вероятно, это неправильно, потому что имена из охватывающей области лямбда также находятся в области лямбда. Если они не захвачены, они могут использоваться, но не могут использоваться в качестве odr, как описано here.

+0

Спасибо. Я просто [зарегистрировал ошибку] ​​(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78850). –

+0

Вы неправильно понимаете, что такое затенение. [Здесь] (http://coliru.stacked-crooked.com/a/04c9525c1ecae0f1) - пример правильного предупреждения тени в clang. Обратите внимание, что программа по-прежнему дает правильный результат, потому что программа верна. (Все еще ошибка в gcc, потому что код Тобиаса не имеет тени). – Oktalist

+0

@Oktalist Это хороший пример того, как будет действовать предупреждение о тене. Я соответствующим образом обновлю ответ. – wally