how can I compare the signatures of 2 functions when one of them is a lambda and the other is a regular function?


Please read this code and my explanation of the question after it:

1
2
3
4
5
6
7
8
9
10
auto lambda = [](unique_ptr<Shape>& ps)
	{
		ps->draw();
	};


template<typename T>
using signature_t = void _cdecl(unique_ptr<T>&);

bool the_same = std::is_same<signature_t<Shape>, decltype(lambda)>::value;


decltype of lambda AND signature_t<Shape> should be the same type -- but decltype(lambda) prefixes the type with the word lambda. Other than that, they are operationally the same. How can I compare them ignoring the fact that one is a lambda while the other isn't? I want to be able to compare their signatures -- ignoring the implementation!

I have working hard on this problem...



Each lambda expression has a class type which is unique. Also, lambdas might not have only one "signature" because their operator() can be a function template.

For example this lambda doesn't really have one "signature" because its operator() is a template which defines a family of different functions.
[](auto x) { return x + 1; }

You can check whether it is possible to call the function object in the way you want:
1
2
3
4
5
template <typename F, typename T>
  concept operation = requires(F f, T x)
  { 
    { f(std::move(x)); } -> std::convertible_to<T>;
  };

Or if you don't care about return type:
1
2
3
4
5
template <typename F, typename T>
  concept operation = requires(F f, T x)
  { 
    f(std::move(x));
  };

See also C++23 std::invoke_r and C++20 std::invocable and C++17 std::is_invocable_r_v, which are more general.

You can also require the user to pass in a pointer to function that has the exact signature you want.
Last edited on
please an example of this:

to pass in a pointer to function that has the exact signature you want.

1
2
3
4
5
6
7
8
template<typename C, typename Oper> requires  contains_unique_ptrs<C>    
void for_all3(C& c, void (op)(is_unique_ptr<Shape>&))
{
	for (auto& x : c)
	{
		op(x);
	}
}


how to write an argument for a function pointer with type:

 
void(is_unique_ptr<Shape>&)


Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <memory>
#include <array>
#include <string>

struct Shape 
{ 
  std::string name; 
  
  explicit Shape(std::string name)
    : name(std::move(name))
  {}
};
  
template <typename C> 
  void for_all3(C& c, void (*op)(std::unique_ptr<Shape>&))
  {
    for (auto& x : c)
    {
      op(x);
    }
  }
  
void print_name(std::unique_ptr<Shape>& ps)
{
  std::cout << (ps? ps->name: "") << "\n";  
}
  
int main()
{
  std::array shapes
  {
    std::make_unique<Shape>("square"),
    std::make_unique<Shape>("circle"),
    std::make_unique<Shape>("triangle")
  };
  
  for_all3(shapes, print_name);
}


Also consider std::function.
1
2
3
4
5
6
7
8
template <typename C> 
  void for_all4(C& c, std::function<void(std::unique_ptr<Shape>&)> op)
  {
    for (auto& x : c)
    {
      op(x);
    }
  }
Last edited on
Topic archived. No new replies allowed.