2013-04-23 52 views
2

這工作:C++模板非類型參數的lambda功能

#include <functional> 

template < bool (*F)(int) > class Foo {}; 

bool fooFunc(int n) { return true; } 

int main(int argc, char* argv[]) 
{ 
    auto a = Foo<fooFunc>(); 
} 

但這不起作用,因爲你不能在lambda轉換爲一個函數指針:

#include <functional> 

template < bool (*F)(int) > class Foo {}; 

auto barFunc = [] (int n) -> bool { return true; }; 

int main(int argc, char* argv[]) 
{ 
    auto a = Foo<barFunc>(); 
} 

這不工作,因爲你不能用std ::功能<>作爲模板非類型參數:

#include <functional> 

template < std::function< bool(int) > F > class Bar {}; 

auto barFunc = [] (int n) -> bool { return true; }; 

int main(int argc, char* argv[]) 
{ 
    auto b = Bar<barFunc>(); 
} 

所以,我該怎麼辦CREA是否能夠接受lambda外殼作爲模板非類型參數的模板類?

+0

注意你的意思是非模板參數。你的意思不是簡單地把'模板'?是否因爲這樣做會放寬模板參數要求以滿足您的需求? – OlivierD 2013-04-23 21:41:29

+1

他意味着一個**值**(與類型相反)模板參數,例如:'template ' – 2013-04-23 21:41:50

+0

我認爲您正在編譯時嘗試做某些事情,在一般情況下無法完成,直到運行這是爲什麼「你不能使用std :: function <>作爲模板非類型參數」 – antlersoft 2013-04-23 21:52:03

回答

5

只需使用類型參數創建類模板,並在實例化模板時使用decltype來推導出lambda的類型。

#include <functional> 

template <typename Function> 
class Bar 
{ }; 

auto barFunc = [] (int n) -> bool { return true; }; 

int main() 
{ 
    auto b = Bar<decltype(barFunc)>(); 
} 


但需要注意的lambda表達式沒有缺省構造的,所以你可能需要添加更多的代碼來創建的Bar一個構造函數的拉姆達的副本:

template <typename Function> 
class Bar 
{ 
    public: 

    Bar(Function f) : m_function(f) 
    { } 

    private: 

    Function m_function; 
}; 
0

在你的第一個例子中,你需要添加一個指針,因爲函數沒有衰減到一個。

int main(int argc, char**) 
{ 
    auto a = Foo< std::add_pointer<decltype(fooFunc)>::type(0) >(); 
} 
+0

有趣。爲什麼'std :: add_pointer :: type(0)'中需要'(0)'? – Ali 2013-04-24 08:06:01