2017-08-22 21 views
3

我有一些代碼處理函數的地址,lambdas和模板參數。lambda需要聯繫的呼叫運營商嗎?

這裏有一個片段,顯示了我的功能,這些地址的一些用法:

#include <type_traits> 

int main() { 
    auto l = []{}; 
    using L = decltype(l); 

    // fine, am I just lucky? 
    using type1 = std::integral_constant<decltype(&L::operator()), &L::operator()>; 

    struct Bar { 
     static void baz() {} 
    }; 

    // error! 
    using type2 = std::integral_constant<decltype(&Bar::baz), &Bar::baz>; 
} 

的事情是,爲了能夠發送&Bar::baz作爲模板參數,它必須有聯繫,因此錯誤。

爲什麼拉姆達的情況下工作?是因爲它不是靜態的,還是因爲lambda的調用操作符有鏈接?

+0

test2在gcc中爲我編譯得很好。你正在使用哪種編譯器? – Frank

+0

成員函數指針是一個值,而不是名稱。價值觀沒有或不需要聯繫。 –

+0

好的...這個例子似乎沒有重現這個問題。我得到了一個輸出錯誤的代碼。我的gcc版本是7.1.1。我將編輯問題 –

回答

3

的λ的閉合類型是一個未命名的類,請參閱[expr.prim.lambda.closure]/1。類的成員函數與其包含的類的名稱具有相同的鏈接(如果有的話);請參閱[basic.link]/5。如果包含類沒有名字(甚至不用於鏈接),那麼它的成員函數就沒有聯繫。

此外,本地拉姆達的閉合類型是一個本地類,和本地類,甚至那些具有一個名字,沒有聯動;見[expr.prim.lambda.closure]/2[basic.link]/8

C++ 17之前,聯動要求,在[temp.arg.nontype]/1.3發現,適用於指針和引用,而不是指向成員。根據這些規則,海灣合作委員會在接受你的lambda情況並拒絕你的情況下是正確的。

N4268完全除去聯動要求用於C++ 17而改造爲模板非類型參數的規則。在C++ 17中,這兩個例子都應該被接受。