2016-12-18 27 views
11

zestawianiu następujący kodParametr zwróconej rodzajowego lambda rzekomo pomocniczym parametru funkcji wolnego

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

g ++ (na przykład p. 5.4) daje 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 

Nie rozumiem dlaczego. Czy ktoś może wyjaśnić?

Odpowiedz

6

To musi być błąd.

  • Zmienna nie jest zasłonięta tak, że nie znajduje się w otaczającej zakresie lambda, jednak nie produce the correct result.
  • VS2015 nie generuje ostrzeżeń.
  • Clang nie generuje ostrzeżeń.

To spekulacyjny, ale to, co dzieje się prawdopodobnie jest następująca substytucja (lub coś podobnego):

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

Ten program does produce a shadow warning on Clang, ale nawet wtedy to daje poprawny wynik. VS2015 nadal nie uważa tego za godne ostrzeżenia, ale jest prawdopodobnie błędne, ponieważ nazwy z otaczającego zakresu lambda również wchodzą w zakres lambda. Jeśli nie są przechwytywane, mogą być używane, ale nie mogą być odr używane zgodnie z wyjaśnieniami here.

+0

Dzięki. Właśnie zgłosiłem błąd (https://gc.gnu.org/bugzilla/show_bug.cgi?id=78850). –

+0

Źle zrozumiesz, czym jest shadowing. [Tutaj] (http://coliru.stacked-crooked.com/a/04c9525c1ecae0f1) jest przykładem poprawnego ostrzeżenia cienia w klangu. Zwróć uwagę, że program nadal generuje poprawny wynik, ponieważ program jest poprawny. (Wciąż jest to błąd w gcc, ponieważ kod Tobiasza nie ma cienia). – Oktalist

+0

@Oktalist To dobry przykład tego, jak ostrzeżenie o cieniu byłoby poprawne. Odpowiednio zaktualizuję odpowiedź. – wally