C++ 是一个C++;纯粹作为库实现的_lambda trait不可能吗?
我有一个关于C++0x lambdas的问题。在我的代码中,了解给定类型是否为C++0x lambda表达式的类型将是有益的。举个例子:C++ 是一个C++;纯粹作为库实现的_lambda trait不可能吗?,c++,lambda,c++11,traits,C++,Lambda,C++11,Traits,我有一个关于C++0x lambdas的问题。在我的代码中,了解给定类型是否为C++0x lambda表达式的类型将是有益的。举个例子: struct foobar { void operator()() { } }; auto lambda = []{}; typedef is_lambda < decltype(lambda) > ::type T; // T would be a true_type typedef is_lambda < foobar &g
struct foobar
{
void operator()()
{
}
};
auto lambda = []{};
typedef is_lambda < decltype(lambda) > ::type T; // T would be a true_type
typedef is_lambda < foobar > ::type T; // T would be a false_type
将适用于lambda表达式和具有非模板调用运算符的函子,并为模板调用运算符生成编译器错误
我相信一个
is_lambda<>
特性只能使用内部编译器特性创建。你看到如何实现这个特性的方法了吗?我不相信这是可以做到的-lambda在语义上并不是什么新东西,它们只是编译器生成的函子,因此看起来与常规函子完全相同。因为对lambda的求值会导致创建闭包对象,只要对象传递给函数或被复制,就没有任何区别。坦率地说,我无法想象一个需要知道物体是否来自lambda的问题
编辑。标准甚至在5.1.2/2中有注释:
注:闭包对象的行为类似于函数对象(20.8)。-结束注
可以定义一些宏代码来确定表达式是否为lambda表达式(但这不是很有用,因为它不会告诉您表达式是否为lambda类型)
#包括
模板
结构SameType{
静态断言(!std::is_same::value,“必须使用Lambda”);
静态T传递(T){return T;}
};
模板
T NotLambda(T,U){return SameType::pass(T);}
#定义ASSERT_LAMBDA(x)NotLambda(x,x)
/////////////////////////////////////
int fn(){return 0;}
int main(){
自动l=[]返回0;};
return ASSERT_LAMBDA(fn)(+/我创建了一个只针对头的编译器(msvc>=19.20?,gcc>=7.3,clang>=6.0)是c++17中的_LAMBDA
类型特征,如果有人感兴趣的话
这可以用在问题中:
struct foobar
{
void operator()()
{
}
};
auto lambda = []{};
typedef bxlx::is_lambda < decltype(lambda) > T; // T is true_type
typedef bxlx::is_lambda < foobar > U; // U is false_type
struct foobar
{
void运算符()()
{
}
};
自动lambda=[]{};
typedef bxlx::is_lambdaT;//T为true_type
typedef bxlx::is_lambdaU;//U为false_类型
还有更多的用法
我想知道你会用它做什么?很抱歉回复太晚。是的,我认为我犯了一个逻辑错误。区分常规函子和lambdas没有任何意义-我可以将后者视为前者。但是,需要确定是否存在调用运算符。到目前为止,似乎还没有针对该问题的完全通用解决方案o存在。我很快会在一个单独的问题中解决这个问题,并尝试解决。@MaximYegorushkin:至于一个激励性的区别:闭包对象的类型唯一地标识了它的实现。不一定是这样的对于其他函数指针或其他类似函数的对象也是如此。我确实认为您可能愿意知道std::function
类型是否是有状态的。但是,由于函数允许使用static
或全局变量,因此它们在区分lambda和混合变量方面没有多大意义。我有同样的想法。我f只有在没有丑陋的宏的情况下才能完成,但是我发现直接使用NotLambda
的语法(使用lambda表达式两次)是可以容忍的,用户当然可以意外地提供两个不同的函数对象。TL;DR:这个想法是用来确定类型的名称,并检查是否看起来像“lambda at foo.cpp”
。
#include <type_traits>
template<typename T, typename U>
struct SameType {
static_assert(!std::is_same<T, U>::value, "Must use Lambda");
static T pass(T t) { return t; }
};
template <typename T, typename U>
T NotLambda(T t, U u) { return SameType<T, U>::pass(t); }
#define ASSERT_LAMBDA(x) NotLambda(x,x)
/////////////////////////////////////
int fn() { return 0; }
int main() {
auto l = []{ return 0; };
return ASSERT_LAMBDA(fn)() + // << fails
ASSERT_LAMBDA(l)() + // << fails
ASSERT_LAMBDA([]{ return 0; })(); // << passes
}
struct foobar
{
void operator()()
{
}
};
auto lambda = []{};
typedef bxlx::is_lambda < decltype(lambda) > T; // T is true_type
typedef bxlx::is_lambda < foobar > U; // U is false_type