Templates 传递lambda的模板专门化
我一直专注于专门化lambda的模板函数:Templates 传递lambda的模板专门化,templates,lambda,c++11,template-specialization,Templates,Lambda,C++11,Template Specialization,我一直专注于专门化lambda的模板函数: class X { public: template <typename T> void f(T t) { std::cout << "awesome" << std::endl; }; template <> void f(double t) { std::cout << "trouble" <
class X
{
public:
template <typename T>
void f(T t)
{
std::cout << "awesome" << std::endl;
};
template <>
void f(double t)
{
std::cout << "trouble" << std::endl; // Works
}
template <>
void f(??? t) // what to put here?
{
std::cout << "lambda" << std::endl;
}
};
X x;
x.f(42); // prints "awesome"
x.f(1.12); // prints "trouble"
x.f([](){ std::cout << "my lazy lambda" << std::endl; }); // should print "lambda"
X类
{
公众:
模板
空隙f(T)
{
std::cout您不能直接这样做:lambda的类型是由编译器创建的,对于每个lambda都是不同的。您可以对它进行专门化,但它只能用于该类型(请参见下面的示例)。您可以通过使用一个小函数来转换lambda->std::function来消除一些繁琐的操作
auto myLambda = [](){ std::cout << "myLambda" << std::endl; };
class X
{
public:
template <typename T>
void f( T t )
{
std::cout << "not so awesome" << std::endl;
};
void f( const std::function< void() >& f )
{
std::cout << "function" << std::endl;
}
void f( const decltype( myLambda )& f )
{
std::cout << "myLambda" << std::endl;
}
};
//helper for lambda -> function
template< class T >
std::function< void() > Function( const T& f )
{
return std::function< void() >( f );
}
X x;
x.f( myLambda ); //prints "myLambda"
x.f( Function( [](){ std::cout << "blah" << std::endl; } ) ); //prints "function"
x.f( [](){ std::cout << "blah" << std::endl; } ); //still won't work: not the same type as myLambda!
auto myLambda=[](){std::cout以下是旧的sizeof技巧的一个变体。也许可以单独使用decltype来完成。它并不确切地检查它是否是lambda,但它是否可调用。如果你想过滤掉其他可调用的东西,你可以使用C++0x类型特征来检查它们是否是函数、成员函数、复合对象等
#include <functional>
#include <iostream>
#include <type_traits>
template<class T>
char is_callable( const T& t, decltype( t())* = 0 );
long is_callable( ... );
class X
{
public:
template <typename T>
void f( const T& t, typename std::enable_if<sizeof(is_callable(t)) !=1>::type* = 0 )
{
std::cout << "awesome" << std::endl;
};
void f(double )
{
std::cout << "trouble" << std::endl; // Works
}
template<class T>
void f( const T& t, typename std::enable_if<sizeof(is_callable(t)) == 1>::type* = 0 )
{
std::cout << "lambda" << std::endl;
}
};
int main(int argc, const char *argv[])
{
X x;
x.f(42); // prints "awesome"
x.f(1.12); // prints "trouble"
x.f([](){ std::cout << "my lazy lambda" << std::endl; }); // should print "lambda"
}
#包括
#包括
#包括
模板
char是可调用的(const T&T,decltype(T())*=0);
long是可调用的(…);
X类
{
公众:
模板
空f(常数T&T,类型名称std::enable_如果::类型*=0)
{
std::cout-related:因此答案似乎是:不,在C++0x中没有办法避免强制转换并专门化一个模板来匹配lambdas,不可能将lambda函数与其他不专门用于lambda的可调用对象区分开来,只有可调用类型-不是同一件事。这可能是最好的方法,可能只是更改sfinae以测试确切的签名,而不是所有可调用的types@DeadMG:我完全可以匹配任何可调用项,只要我可以避免最后一行永远不会匹配lambda,因为每个lambda都有不同的唯一类型