Considere este código ( godbolt ):
#include <iostream>
template<typename F> void call_by_val(F funct)
{
std::cout << "call_by_val(): ";
funct();
}
template<typename F> void call_by_ref(F& funct)
{
std::cout << "call_by_ref(): ";
funct();
}
template<typename F> void call_by_cref(const F& funct)
{
std::cout << "call_by_cref(): ";
funct();
}
void free_funct()
{
std::cout << "free_funct()\n";
}
int main()
{
call_by_val( free_funct );
call_by_ref( free_funct );
call_by_cref( free_funct );
}
Todas essas três chamadas funcionam como esperado. No caso de uma função livre, não tenho certeza do que está acontecendo por baixo do tapete, então estou pensando qual é a diferença entre esses três estilos, semanticamente falando. Existe uma razão objetiva para preferir um em vez dos outros?