0

I have one class Hunter that has a member function random_hunt which returns a pair<int, int> const that's supposed to be equivalent to some point (x, y). I'm trying to implement a second member function test_hunt which will return the number of tries it takes the random_hunt to land on a target point given the target pair, the member function itself, and the class itself.

I have attempted two implementations:

class Hunter {
        // 1
    int test_hunt(std::function<pair<int, int> const()> func, pair<int, int>& const target) {
        int tries = 0;
        while (target != func())
            tries++;
        return tries;
    }

        // 2
    int test_hunt(pair<int, int> const (Hunter::* func)(), Hunter& hunter, pair<int, int>& const target) {
        int tries = 0;
        while (target != (hunter.*func)())
            tries++;
        return tries;
    }
};

in main:

Hunter hunter;

auto fp = std::bind(&Hunter::random_hunt);
std::cout << hunter.test_hunt(fp, r_start_pos) << '\n';

std::cout << hunter.test_hunt(&Hunter::random_hunt, hunter, r_start_pos) << '\n;

Neither compile and I'm not sure why. I've looked at previous examples that do something similar using member functions of void return type and they seem to work fine. Is it the return type in my case that's making the difference, or have I simply implemented the function incorrectly?

10
  • 2
    OT: Returning by constant value (like std::pair<int, int> const) is useless. Nothing stops the caller to save a copy that can be modified. Commented Oct 20, 2023 at 3:11
  • 1
    As for your problem, templates and lamdas is my recommendation. template<typename F> int test_hunt(F func, ...) { func(...); } and call like object1.test_hunt([&object2](...) { object2.random_hunt(...); }, ...) Commented Oct 20, 2023 at 3:14
  • Or even better, come up with a design that doesn't need you to pass a function as argument. Commented Oct 20, 2023 at 3:15
  • 1
    std::pair (and tuple) are intended to be used for either template progamming of for pairs meaningless numbers. In all other cases you should declare a struct (with two values) and return that. @Someprogrammerdude I disagree, it declares an intent (e.g. returning an encrypted string). The extra line that copies might trigger questions during a code review (just like const_cast would). Code is also about semantics Commented Oct 20, 2023 at 4:47
  • 1
    My comment is about returning a constant object by value. Returning a reference to constant object is a different thing. Commented Oct 20, 2023 at 13:34

1 Answer 1

1

With std::bind you need to pass object pointer as well along with method, like

 auto fp = std::bind(&Hunter::random_hunt,&hunter);

Here is compiled code.

Sign up to request clarification or add additional context in comments.

3 Comments

What if I wanted to add an argument to the random_hunt function?
When do you want to specify the argument? Within main or within test_hunt?
@NathanXu, you can pass argument either while creation function object(with bind) or while using that object. Check example of std::bind en.cppreference.com/w/cpp/utility/functional/bind

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.