C++ c++;模板非类型参数lambda函数

C++ c++;模板非类型参数lambda函数,c++,templates,c++11,lambda,C++,Templates,C++11,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 >(); } #包括 模板类Foo{}; boolfoofunc(int n){返回真;} int main

这项工作:

#include <functional>

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

bool fooFunc( int n ) { return true; }

int main( int argc, char* argv[] )
{
    auto a = Foo< fooFunc >();
}
#包括
模板类Foo{};
boolfoofunc(int n){返回真;}
int main(int argc,char*argv[])
{
自动a=Foo();
}
但这不起作用,因为无法将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 >();
}
#包括
模板类Foo{};
auto barFunc=[](int n)->bool{return true;};
int main(int argc,char*argv[])
{
自动a=Foo();
}
这不起作用,因为不能将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 >();
}
#包括
模板F>class Bar{};
auto barFunc=[](int n)->bool{return true;};
int main(int argc,char*argv[])
{
自动b=Bar();
}

那么,如何创建一个能够接受lambda附件作为模板非类型参数的模板类呢?

只需创建一个带有类型参数的类模板,并在实例化模板时使用
decltype
推断lambda的类型

#include <functional>

template <typename Function> 
class Bar 
{ };

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

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

在第一个示例中,您需要添加一个指针,因为函数没有退化为指针

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

请务必注意非类型模板参数的含义。你的意思不是简单地把
模板
?这是因为这样做会过分放松模板参数的要求以满足您的需要吗?他指的是一个值(与类型相反)模板参数,例如:
template
,我认为您试图在编译时做一些在运行时之前在一般情况下无法完成的事情,这就是为什么“您不能将std::函数用作模板非类型参数”如果从
[](int)->bool
转换为
bool(*)(int)
was
constexpr
,这将很容易做到。如果标准中说没有lambda捕获的lambda表达式的闭包类型具有一个公共非虚拟非显式const转换函数,该函数指向与闭包类型的函数调用运算符具有相同参数和返回类型的函数指针。“
constepr
而不是
const
这是可行的。但标准是保守的。我想不出一个技术上的原因来解释为什么转换不应该是
constexpr
,其他人可以吗?很有趣。为什么在
std::add\u pointer::type(0)
中需要
(0)
int main( int argc, char** )
{
    auto a = Foo< std::add_pointer<decltype(fooFunc)>::type(0) >();
}