Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Since C++ 20, the concepts have been released to constrain templates and auto.

I wanted to create a concept that only defines a lambda, is it possible?

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

And then I could apply like this:

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

lambda auto func1 = []{ return 5; }; // constrain satisfied
lambda auto func2 = add; // constrain unsatisfied, compilation error.
like image 392
Desmond Gold Avatar asked Nov 27 '25 07:11

Desmond Gold


2 Answers

You can get the type name of T at compiler time, and then determine whether it contains the mangled name of lambda, which starts with <lambda in gcc and (lambda in clang:

Although it is feasible, it is actually not recommended.

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

like image 167
康桓瑋 Avatar answered Nov 28 '25 20:11

康桓瑋


I don't know why you'd want this, but the closest I can think of is this:

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

Compiler Explorer link

Basically, this requires that T has a call operator. This works because that's how lambdas are implemented: they give you an object whose type has a compiler generated operator().

However, this concept accepts things that are not lambdas, namely user defined structs that have call operators, such as std::function, std::bind, std::reference_wrapper, etc. Thus, this concept accepts basically all callables which are not function pointers, which is a strange categorization of C++ function objects.

like image 42
Justin Avatar answered Nov 28 '25 21:11

Justin