2016-06-22 36 views
5

我寫了一些代碼給出一個通用的lambda函數時檢索類型的非汽車類的參數。正如你在下面的代碼中看到的,這個想法是用一個通用的lambda調用connect函數,併爲自動參數提供參數(它總是在我的用例的前面)。所以在下面的代碼中,我的目標是檢測第二個參數是float類型。檢測參數類型從通用拉姆達 - 編譯錯誤使用GCC

的代碼工作正常鏗鏘3.8,但它並沒有用gcc 6.1.1編譯,所以我想知道這是否是海灣合作委員會中的錯誤,或者這僅僅是無效的C++代碼?我可以假設一個通用的lambda是使用模板化的operator()函數實現的還是這個編譯器特定的?

template <typename Functor, typename... AllArgs, typename... ProvidedArgs> 
void findArgTypes(void(Functor::*)(AllArgs...) const, Functor, ProvidedArgs...) 
{ 
    // AllArgs == int, float 
    // ProvidedArgs == int 
} 

template <typename Func, typename... ProvidedArgs> 
void connect(Func func, ProvidedArgs... providedArgs) 
{ 
    findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...); 
} 

int main() 
{ 
    int tmp = 0; 
    connect([&](auto, float){ ++tmp; }, 0); 
} 

是GCC給出了錯誤是這樣的:

main.cpp: In instantiation of ‘void connect(Func, ProvidedArgs ...) [with Func = main()::<lambda(auto:1, float)>; ProvidedArgs = {int}]’: 
main.cpp:16:33: required from here 
main.cpp:11:17: error: no matches converting function ‘operator()’ to type ‘void (struct main()::<lambda(auto:1, float)>::*)() const’ 
    findArgTypes(&Func::template operator()<ProvidedArgs...>, func, providedArgs...); 
    ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
main.cpp:16:27: note: candidate is: template<class auto:1> main()::<lambda(auto:1, float)> 
    connect([](auto, float){}, 0); 
         ^

去除findArgTypes的const給出了相同的結果。

使用下面的代碼用兩種編譯器的工作原理:

struct Foo 
{ 
    template <typename T> 
    void operator()(T, float) const {} 
}; 

int main() 
{ 
    Foo f; 
    connect(f, 0); 
} 

回答

1

你,因爲你期待仿函數(對象),但拉姆達空捕獲有錯誤可轉換爲免費功能:

int main() { 
    using function = void (*)(int, float); 
    function a = [](auto, float){}; 
} 

lambda from cppreference


對於最新版本的問題,落實滿足兩種編譯器:

template <typename Func, typename... ProvidedArgs> 
void connect(Func func, ProvidedArgs... providedArgs) 
{ 
    auto mf = &Func::template operator()<ProvidedArgs...>; 
    findArgTypes(mf, func, providedArgs...); 
} 

我覺得這是gcc編譯器錯誤,GCC需要這個auto局部變量的正常工作......

BTW,有一個問題 - 一個臭蟲鐺,一個在GCC - 我真的建議你找到更簡單的方式來實現自己的目標 - 也許考慮只使用std::function代替挺新鮮的仿製拉姆達的?

+0

該代碼似乎編譯使用gcc但不是鏗鏘。但是改變我的代碼以使用'void(*)(AllArgs ...)'作爲findArgTypes的第一個參數仍然會給gcc帶來同樣的錯誤(並且不再與clang一起使用)。捕獲局部變量似乎也沒有什麼區別。 – texus

+0

您需要兩個重載函數 - 一個免費的功能,一個目標函數 - 或者只是改變一點點你的設計... – PiotrNycz

+0

鐺可能是錯誤的 - 看到鏈接的頁面例如:'INT&(* FPI)爲(int *)= [](auto * a) - > auto&{return * a; }; // ok' – PiotrNycz