1

Can someone explain me why some of these implementation works while other doesn't and what's happening under the hood? Is there some performance issue for example with f1?

What should I google for finding these mapping rules?

#include<string> 
#include <algorithm>
#include <vector> 
#include <iostream>
#include <functional> 

bool f1(const std::string& str1)  //works
{
    std::cout<<"f1"<<str1<<std::endl;
    return true;
}

bool f2(std::string& str1) //not working
{
    std::cout<<"f2"<<str1<<std::endl;
    return true;
}

bool f3(std::string str1) //works
{
    std::cout<<"f3"<<str1<<std::endl;
    return true;
}

bool f4(std::string* str1)
{
    std::cout<<"f4"<<str1<<std::endl;
    return true;
}

int main(){
    std::function<bool(std::string)> fp=&f1;
    std::string x="Hello world";
    fp(x);
    return 0;
}
Fzza
  • 105
  • 1
  • 9
  • Which of the multiple things wrong here are you struggling with? I suspect it's `"Hello world"` not being a `std::string` (it is a [String Literal](https://en.cppreference.com/w/cpp/language/string_literal), a dumb old null-terminated array of `char`), thus requiring conversion and a temporary variable to store the converted value, and not being able to take references and pointers to temporaries because of their extremely short lifespans. – user4581301 Nov 22 '22 at 16:55
  • 1
    Recommendation: If my suspicion is correct, remove the `std::function` from the equation to focus on the problem better. If you're having problems with the `std::function`, you'll want to focus on it instead. – user4581301 Nov 22 '22 at 16:58
  • Related: https://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object – YSC Nov 22 '22 at 17:01
  • Removed tmp object created. My question is why some of these functions can be binded to fp while other can't? – Fzza Nov 22 '22 at 17:06

1 Answers1

2

As explained on cppreference, you can assign a function f to a std::function<R(Args...)> if f is callable for argument types Args... and return type R.

In your example, f1 and f3 work because you can call either of them with a std::string rvalue. You can't call f2 or f4 with a std::string rvalue.

Nelfeal
  • 12,593
  • 1
  • 20
  • 39
  • It's not clear to me why I can't call f2 that receives a `std::string&` passing a `std::string` – Fzza Nov 23 '22 at 13:23
  • @Francesco.S Non-const references don't bind to rvalues. I'm not sure why it has to be an rvalue, but it's in the definition of callable: `INVOKE(f, std::declval()...)` must be well-formed and the `std::declval` part makes rvalues. – Nelfeal Nov 23 '22 at 14:57