Problem when std::function refers to member function

In summary: Would it be better to implement the function dev_b::ShowB as member function of master_t instead, so it can have access to both dev_a and dev_b objects?It depends on your design and the specific needs of your code. It is possible to implement ShowB() as a member function of master_t and access both dev_a and dev_b objects, but it may not be necessary or appropriate in all cases.
  • #1
ORF
170
18
Hi,

I have a class master_t which is composed by two other classes, dev_a, dev_b. I would like that a member function from the dev_b object (within master_t) could use a member function of dev_a object (within master_t). This is a minimal working code, where line 26 implements this feature.

Minimal working example:
class dev_a
{
public:
int a = {1}; 
void ShowA( ){ std::cout << "dev_a::a = " << a << '\n'; return; }
};

class dev_b
{
public:
int b = {2}; 
void ShowB( std::function<void(void)> ShowA ){ std::cout << "dev_b::b = " << b << '\n'; ShowA(); return; }
};

class master_t
{
public:
  dev_a one;
  dev_b two;
};
 
// Driver code
int main()
{
    master_t obj;
    obj.two.ShowB( [&](){ obj.one.ShowA(); return;} );
    return 0;
}

I naively tried first with obj.two.ShowB( obj.one.ShowA ); but I got the following error

Error message:
error: no matching function for call to ‘dev_b::ShowB(<unresolved overloaded function type>)’
     obj.two.ShowB( obj.one.ShowA );

I have two questions:
a) The cause of the error is because when passing the function like obj.two.ShowB( obj.one.ShowA ); is missing the reference to the actual object obj.one?
b) Would it be better to implement the function dev_b::ShowB as member function of master_t instead, so it can have access to both dev_a and dev_b objects?

Thank you for your time. Any comment is welcome.

Cheers,
ORF
 
Technology news on Phys.org
  • #2
Your code worked fine for me, and produced this output:
Code:
dev_b::b = 2
dev_a::a = 1

Maybe I am missing the point of your question ... ?

It seems simpler to me to implement ShowB() similar to how ShowA() is implemented. That would eliminate the need for the convoluted code of line 26 - obj.two.ShowB( [&](){ obj.one.ShowA(); return;} );. This line truly deserves some commenting.

To make your code compile and run, I added the following lines at the top.
C++:
#include <iostream>
#include <functional>
using std::cout;
using std::function;
 
Last edited:
  • #3
ORF said:
The cause of the error is because when passing the function like obj.two.ShowB( obj.one.ShowA ); is missing the reference to the actual object obj.one?
That is correct. You can use a lambda to capture and call the object, or you can use std::bind, for example like
C++:
obj.two.ShowB( std::bind(&dev_a::ShowA, &obj.one) );
 
  • Like
Likes ORF and jim mcnamara

FAQ: Problem when std::function refers to member function

What is the "problem" when std::function refers to a member function?

The problem arises when a member function is passed as an argument to std::function, which is a type-erased function wrapper. This can cause issues with type deduction and cause the code to fail to compile.

How does this problem affect my code?

This problem can cause errors during compilation, making it difficult to debug and fix the issue. It can also lead to unexpected behavior at runtime, potentially causing program crashes or incorrect results.

Can this problem be avoided?

Yes, this problem can be avoided by using a lambda function instead of a member function when passing a function as an argument to std::function. Lambdas are automatically converted to function pointers, which can be passed to std::function without any issues.

Are there any alternative solutions to this problem?

Another solution is to use std::bind to bind the member function to a specific object instance before passing it to std::function. This ensures that the correct type is passed to std::function and avoids any type deduction issues.

Is it recommended to use std::function to refer to member functions?

It is generally not recommended to use std::function to refer to member functions. Instead, it is better to use function pointers or lambdas, as they are more efficient and avoid potential issues with type deduction.

Similar threads

Replies
13
Views
2K
Replies
8
Views
2K
Replies
22
Views
3K
Replies
36
Views
4K
Replies
57
Views
4K
Replies
6
Views
10K
Replies
4
Views
2K
Back
Top