2013-04-23 73 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