-1

Trying to call a function that gets used as an argument for another function, while passing it's own arguments. Example in pseudoish c++ code:

void function1(argument(x)) ///I believe this should be void function1(void(*argument)(int)), but i try to call it as *argument(); and that fails also
{
    doStuff;
    argument(x);
    doMoreStuff;
}

void function2(int x)
{
     int test;
     test = x + 2;
     doOtherStuffWithx;
}

int main()
{
    int test = 1;
    sample = function1(function2(test));
}



haven't been able to figure it out. Any help would be greatly appreciated.

Cliff Ribeiro
  • 77
  • 1
  • 1
  • 7
  • You might consider a [functor](https://stackoverflow.com/q/356950/10077). – Fred Larson Nov 04 '21 at 20:27
  • 1
    std::bind allows you to bind the function pointer to the argument so that it can still be called later. That way you only have to pass a single parameter to function1: https://onlinegdb.com/Tf6M6auHG – Jerry Jeremiah Nov 04 '21 at 20:40
  • @JerryJeremiah: I think that would make a good answer. – Fred Larson Nov 04 '21 at 20:43
  • `function1` declaration is not valid or "well-formed" C or C++. May be it was 25 years ago with _implicit-int_ and _optional-return-type_ rules, but not nowadays. You should fix that error first or use a compiler from that era. – Maxim Egorushkin Nov 04 '21 at 20:46
  • 1
    @MaximEgorushkin: I think fixing that error would be the answer the OP is looking for, hence why it is referred to as "pseudoish c++ code". – Fred Larson Nov 04 '21 at 20:52
  • @FredLarson Oh, I see now, said a blind man. Voting to close as non-reproducible. – Maxim Egorushkin Nov 04 '21 at 20:53
  • 1
    @JerryJeremiah `std::bind` was needed before C++11. In C++11 and on `std::bind` is worse in space and time than C++11 lambda captures, and, therefore, `std::bind` shouldn't ever be used. `std::bind` is essentailly C++03 poor man's C++11 lambda capture. – Maxim Egorushkin Nov 04 '21 at 21:02
  • @MaximEgorushkin Fair enough. And that's why it was a comment instead of an answer. However, I don't think std::bind existed before C++11 - before that everyone used Boost.Bind, didn't they? According to https://en.cppreference.com/w/cpp/utility/functional/bind std::vind is since C++11. Anyway, I don't know what version of C++ the OP can use - perhaps that version doesn't have lambdas. – Jerry Jeremiah Nov 04 '21 at 21:29
  • @JerryJeremiah `boost::bind` wanted to be a part of C++ standard before C++03. It only got included in C++11, but native lambdas got there at the same time making `std::bind` unnecessary. But it wasn't clear if any of `std::bind` or native lambdas would get into C++11 at all. – Maxim Egorushkin Nov 04 '21 at 21:43
  • @JerryJeremiah `boost` is the origin of these libraries that later got into `std`. By the time `boost` libraries get into `std`, the latter is merely an old and incomplete version of current `boost`, so I never switched to `std` knock-offs. `boost` also fixes mistakes even if that breaks the ABI, whereas `std` versions bit-rot unmodified until they become barely usable and deprecated. – Maxim Egorushkin Nov 04 '21 at 22:13

2 Answers2

1

The simplest for you would be to program it like that:

#include <functional>

void function1(std::function<void(int)> func, int arg)
{
    //doStuff;
    func(arg);
    //doMoreStuff;
}

void function2(int x)
{
     int test;
     test = x + 2;
     //doOtherStuffWithx;
}

int main()
{
    int test = 1;
    function1(function2, test);
}

If you want to use some function with arbitrary number of arguments and types, then you can use templates:

template<typename F, typename... Args>
void function1(F&& func, Args&&... args)
{
    //doStuff;
    func(std::forward<Args>(args)...);
    //doMoreStuff;
}
Alexey S. Larionov
  • 6,555
  • 1
  • 18
  • 37
  • so std::function acts as a wrapper in this case? Would a reference be the same? – Cliff Ribeiro Nov 04 '21 at 20:33
  • `function1` function template would avoid conversion to `std::function`, which may involve memory allocations. There is a tradeoff between zero overhead and having to expose `function1` implementation and non-zero overhead of `std::function` and not having to expose `function1` implementation. – Maxim Egorushkin Nov 04 '21 at 21:10
0

The simplest way to do this is to use a lambda expression calling the function with the desired parameter, and pass that as a std::function that your function1() accepts:

#include <iostream>
#include <functional>

void function1(std::function<void()> f)
{
    std::cout << "Stuff before...\n";
    f();
    std::cout << "... stuff after.\n";
}

void function2(int x)
{
     int test;
     test = x + 2;
     std::cout << test << '\n';
}

int main()
{
    int test = 1;
    function1([=]() { function2(test); });
}
Fred Larson
  • 60,987
  • 18
  • 112
  • 174