2011-09-02 16 views
6

次の例では、私はVC++ 2010年に発生した問題を示していますlambdaから関数を呼び出す際の参照ルールは何ですか?

class Foo 
{ 
    template<class T> 
    static T foo(T t) { return t; } 

public: 
    void test() 
    { 
     auto lambda = []() { return foo(1); }; // call to Foo::foo<int> 
     lambda(); 
    } 
}; 

VC++を生成します。エラーC3861:'foo'を:この例Foo::foo(1);:私はfooへの呼び出しを修飾した場合、識別子は

が見つかりません 警告C4573:'Foo::foo'を使用すると、コンパイラは'this'をキャプチャする必要がありますが、現在のデフォルトのキャプチャモードでは許可されません。

標準はこのケースについて何を言っていますか?修飾されていない名前が見つかるはずですか?修飾名はキャプチャする必要がありますthis

+0

ええ、それは変です。それは静的なので、 'this'は必要ないはずです。私はそれがコンパイラのバグだと思うし、それを見つけられないということはコンパイラがコンパイラの副作用であると思っているので、それを使うのに 'this 'が必要だと思っている。 –

+0

これはg ++でも起こりますので、バグのようには見えません。それを[]()の代わりに[&]()に変更すると、これはうまくコンパイルされますが、それはこれを参照するためです。 – DrYap

+0

[別のスレッド](http://stackoverflow.com/questions/4940259/c0x-lambdas-require-capturing-this-to-call-static-member-function)はバグだと言っています。 – DrYap

答えて

4

マイクロソフトでは、この問題が多くのケースで報告されています。参照:

Scope Resolution with lambdas interferes with namespace and type resolution

Template resolution in lambdas

をあなたが見つけたてきたように、明示的な解像度は、それが名前を見つけることができます。これについての追加の警告もあります。これはコンパイラのエラーです(名前解決はこれにアクセスする必要はありませんが、コンパイラの実装にはどのように必要なのか分かります)。マイクロソフトでは、これがバグであることを確認しており、次のリリースの修正プログラムを用意しているようです。

2

次のコードは正しくコンパイルされます。これはちょうどテンプレートのVSバグでなければならないと私には思われます。

struct Foo { 
    static void foo() {} 
    void bar() { 
     auto f = []() { foo(); }; 
     f(); 
    } 
}; 
+0

どのコンパイラを試しましたか?コンパイラによって結果が異なるようですので、標準に準拠した動作を知ることが重要です。 –

+0

@Gene:VC++ 2010はlambdas pre- [N2927](http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2927.pdf)を実装しているため、**ではありません* * FDISの言い回しに準拠しています。 – ildjarn

関連する問題