C++ 是一个C++;纯粹作为库实现的_lambda trait不可能吗?

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

我有一个关于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 > ::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