Utopia
Utopia

Reputation: 278

Pass another argument to functor's library

I would like to pass another argument to a function from libtins library like that :

for (int i = 0; i < sizeof(dates); i++) {
    FileSniffer sniffer("/path/" + dates[i] + ".pcap");
    sniffer.sniff_loop(doo, i);
}

So that I can use parameter i in my function like that:

    bool doo(PDU &pdu, int i) {
    const IP &ip = pdu.rfind_pdu<IP>();
    files[i] << ip.src_addr() << std::endl;
    return true;

However, this is not possible as the function sniff_loop is defined in the library and takes only one argument. In this case, should I modify the function's behavior, or is there a better solution to recover i in function sniff_loop?

Upvotes: 0

Views: 150

Answers (3)

anni
anni

Reputation: 1463

Try using std::bind

#include <functional>

bool doo(PDU &pdu, int i) {
    const IP &ip = pdu.rfind_pdu<IP>();
    files[i] << ip.src_addr() << std::endl;
    return true;
}

for (int i = 0; i < sizeof(dates); i++) {
    FileSniffer sniffer("/path/" + dates[i] + ".pcap");
    sniffer.sniff_loop(std::bind(&doo, std::placeholders::_1, i));
}

Upvotes: 1

R Sahu
R Sahu

Reputation: 206737

or is there a better solution?

If the library can work with a callable object, such as a functor, a lambda, or a std::function, there are elegant solutions. If not, you'll need to:

  1. Store i in a variable in a suitable scope so that yourcall back function can use it.

  2. Define a callback function that matches the signature of the function required by the library. Use that function in the call to the library.

  3. Call the function you posted from the previous function using the value of i stored in the other variable.


bool doo_2(PDU& pdu);
static int loop_variable = 0;

for (int i = 0; i < sizeof(dates); i++) {
    FileSniffer sniffer("/path/" + dates[i] + ".pcap");
    loop_variable = i;
    sniffer.sniff_loop(doo_2);
}

bool doo(PDU& pdu, int i) {
   const IP &ip = pdu.rfind_pdu<IP>();
   files[i] << ip.src_addr() << std::endl;
   return true;
}

bool doo_2(PDU &pdu) {
   doo(dpu, loop_variable);
}

From the link you posted in a comment

This method takes a template functor as an argument, which must define an operator with one of the following signatures:

That indicates to me that you should be able to use a lambda function.

auto fn = [i] (PDU& pdu) -> bool { return doo(pdu, i); };
sniffer.sniff_loop(fn);

Upvotes: 1

aram
aram

Reputation: 1444

Yes just just use a lambda

sniffer.sniff_loop([i] (PDU &pdu) -> bool {
    doo(pdu, i);
});

Upvotes: 1

Related Questions