2015-08-19 55 views
34

問題:通過一個通用的λ(一個模板函數)捕獲this並調用this一個成員函數沒有明確this->沒有就GCC。如果lambda不是泛型的,或者lambda沒有傳遞給任何其他函數,但是已經調用,它就會編譯一個明確的this->。在所有情況下,Clang都很酷。調用`從通用拉姆達this`成員函數 - 鐺VS GCC

時間爲另一輪鐺vs gcc。誰是對的?

Wandbox example


template<typename TF> 
void call(TF&& f) 
{ 
    f(1); 
} 

struct Example 
{   
    void foo(int){ } 

    void bar() 
    { 
     call([this](auto x){ foo(x); }); 
    } 
}; 

int main() 
{ 
    Example{}.bar(); 
    return 0; 
} 

  • 隨着bar() = call([this](auto x){ foo(x); });
    • 鐺++ 3.6+ 編譯
    • g ++ 5.2+ 不能編譯。

      error: cannot call member function 'void Example::foo(int)' without object call([this](auto x){ foo(x); });`


  • 隨着bar() = call([this](auto x){ this->foo(x); });
    • 鐺++ 3.6+ 編譯
    • g ++ 5.2+ 編譯。

  • 隨着bar() = call([this](int x){ foo(x); });
    • 鐺++ 3.6+ 編譯
    • g ++ 5.2+ 編譯。

  • 隨着bar() = [this](auto x){ foo(x); }(1);
    • 鐺++ 3.6+ 編譯
    • g ++ 5.2+ 編譯。

爲什麼只在一個通用的拉姆達的情況下,必要的this->

爲什麼this->沒有必要,如果lambda沒有傳遞給call

誰不符合標準?

+3

您注意到的不一致表明clang在這裏是正確的。 –

+7

甚至沒有看標準,我可以絕對肯定地說Cla是正確的。即使它不同意這個標準,它仍然是正確的。在這種情況下,標準是錯誤的。 GCC的行爲毫無意義。 –

+2

[相關但不是愚蠢?](http://stackoverflow.com/q/20312062/819272) – TemplateRex

回答

12

這是一個海灣合作委員會的錯誤。從[expr.prim.lambda]:

The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), determining the type and value of this (9.3.2) and transforming id-expressions referring to non-static class members into class member access expressions using (*this) (9.3.1), the compound-statement is considered in the context of the lambda-expression. [ Example:

struct S1 { 
    int x, y; 
    int operator()(int); 
    void f() { 
     [=]()->int { 
      return operator()(this->x + y); 
       // equivalent to S1::operator()(this->x + (*this).y) 
       // this has type S1* 
     }; 
    } 
}; 

—end example ]

因爲在你的榜樣,你捕捉this,名稱查找應包括Example類的成員,因此它應該找到Example::foo。執行查找是相同的會發生什麼,如果foo(x)出現在拉姆達表達本身的上下文,即如果代碼看起來像:

void bar() 
{ 
    foo(x); // clearly Example::foo(x); 
} 

至少這個錯誤有一個非常簡單的解決方法指示在問題中:只是做this->foo(x);

+0

是否有上溯的錯誤報告來跟蹤它? – jotik

+0

@jotik是的,OP [報告它](http://stackoverflow.com/questions/32097759/calling-this-member-function-from-generic-lambda-clang-vs-gcc/32098850#comment52090459_32097759)。 – Barry

+1

表示在此處跟蹤錯誤:https://gcc.gnu.org/bugzilla/show_bug.cgi?id = 67274 –

相關問題