2016-12-18 1 views
11

グラムで、次のコードパラメータは、伝えられるところでは無料の関数のパラメータ

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

をコンパイル++(例えば、V。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-usedされないかもしれません。here

+0

ありがとうございました。私は[バグを提出しました](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78850)。 –

+0

あなたはシャドウイングが何であるか誤解しています。 [ここ](http://coliru.stacked-crooked.com/a/04c9525c1ecae0f1)は、clangの正しいシャドウ警告の例です。プログラムが正しいので、プログラムは正しい結果を生成することに注意してください。 (Tobiasのコードにはシャドーイングがないので、まだgccのバグです。) – Oktalist

+0

@Oktalistこれは、シャドウ警告がどのように有効であるかの良い例です。私はそれに応じて答えを更新します。 – wally

関連する問題