12

我有一个关于 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 表达式与函数和成员函数类型区分开来相当容易。函子是另一回事。

我在这里看到的问题是根据即将到来的 C++0x 标准定义 lambda 表达式;唯一必须定义的是公共呼叫操作员。然而,对于函子也是如此;测试调用运算符的存在不足以区分 lambda 表达式和仿函数。此外,如果函子的运算符存在,则会发生编译器错误,因为 SFINAE 不适用。这什么时候发生?函子的调用操作符可以被模板化。所以,这样的代码:

typedef decltype(&T::operator()) call_type;

将适用于具有非模板化调用运算符的 lambda 表达式和仿函数,并为模板化调用运算符生成编译器错误。

我相信is_lambda < >只能使用内在编译器功能创建特征。您是否看到了如何实现此特征的方法?

4

4 回答 4

8

由于对 lambda 的评估会导致创建闭包对象,因此只要将对象传递给函数或复制,就没有任何区别。而且,坦率地说,我无法想象需要知道一个对象是否来自 lambda 的问题。

编辑。一个标准甚至在 5.1.2/2 中有一个注释:

注意:闭包对象的行为类似于函数对象(20.8)。——结束注释

于 2011-01-11T19:55:08.493 回答
6

我不相信它可以完成 - lambdas 在语义上并不是什么新东西,它们只是编译器生成的仿函数,因此看起来与常规仿函数相同。

于 2011-01-11T19:54:05.553 回答
2

可以定义一些宏代码来确定表达式是否为 lambda表达式(但这不是很有用,因为它不会告诉您表达式是否为 lambda类型)。

#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
}

这取决于第 5.1.2.3 节,它指定每个 lambda 表达式都有一个不同的类型(我认为这是 lambdas 独有的属性)。

于 2014-03-28T22:31:11.013 回答
1

is_lambda如果有人感兴趣,我在 c++17 中创建了一个仅标头编译器特定的 (msvc >= 19.20?, gcc >= 7.3, clang >= 6.0)类型特征。

https://github.com/schaumb/is_lambda-cpp-type-trait

这可以在问题中使用:

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

还有更多的用法示例


于 2020-01-14T15:08:49.543 回答