是否可以创建一个只有 lambda 的概念?

Is it possible to create a concept that is only a lambda?

从C++ 20开始,发布了约束模板和自动的概念。

我想创建一个只定义 lambda 的概念,这可能吗?

template <typename T>
concept lambda = /* ... */ ;

然后我可以这样申请:

int add(int x, int y) {
    return x + y;
}

lambda auto func1 = []{ return 5; }; // constrain satisfied
lambda auto func2 = add; // constrain unsatisfied, compilation error.

我不知道你为什么想要这个,但我能想到的最接近的是:

template <typename T>
concept lambda = requires { &T::operator(); };

Compiler Explorer link

基本上,这需要 T 有呼叫操作员。这是可行的,因为这就是 lambda 的实现方式:它们为您提供一个对象,其类型由编译器生成 operator().

但是,这个概念接受不是 lambda 的东西,即具有调用运算符的用户定义结构,例如 std::functionstd::bindstd::reference_wrapper 等。因此,这个概念基本上接受所有不是函数指针的可调用对象,这是 C++ 函数对象的一个​​奇怪分类。

可以在编译时得到T的类型名,然后判断是否包含lambda的mangled name,在gcc中以<lambda开头,在gcc中以(lambda开头铿锵声:

虽然可行,但其实不推荐

#include <string_view>

template <typename T>
consteval bool is_lambda() {
  std::string_view name = __PRETTY_FUNCTION__;
  auto pos = name.find("T = ");
  name.remove_prefix(pos + 4);
  if (pos = name.rfind("::"); pos != name.npos) 
    name.remove_prefix(pos + 2);
#ifdef __clang__
  return name.starts_with("(lambda");
#elif defined(__GNUC__)
  return name.starts_with("<lambda");
#endif
}

template <class T>
concept lambda = is_lambda<T>();

Demo.