Trying to run a non-generic function but it is overloaded by a template function.
The problem is that they take rvalue references as arguments.
Here's what it kinda looks like:
#include <iostream>
using namespace std;
template <typename T> void bar(T &b) { cout << "bar <template> called\n" ; }
template <typename T> void foo(T &&b) { cout << "foo <template> called\n" ; }
void bar(string &b) { cout << "bar <string> called\n" ; }
void foo(string &&b) { cout << "foo <string> called\n" ; }
int main() {
string msg_a = "hello a";
string msg_b = "hello b";
int a = 1;
int b = 2;
bar(a);
bar(msg_a);
bar(b);
bar(msg_b);
cout << "\n";
foo(a);
foo(msg_a); // <-- I want this to call the 'void foo(string &&b)' but it doesn't
foo(b);
foo(msg_b); // <-- I want this to call the 'void foo(string &&b)' but it doesn't
return (0);
}
Output:
bar <template> called
bar <string> called
bar <template> called
bar <string> called
foo <template> called
foo <template> called
foo <template> called
foo <template> called
When I call foo()
with a type string
I would like it to call the void foo(string &&b)
function but instead it calls the template <typename T> void foo(T &&b)
function.
Whereas as you can see with the functions that take an lvalue reference this is not a problem and the priority is held as normal.
Does anyone know a fix or work around for this ?
foo(msg_a)
cannot ever call void foo(string &&b)
as that particular overload only accepts rvalues of type string
, while msg_a
is an lvalue expression. The only viable fallback is therefore template <typename T> void foo(T &&b)
, which accepts a forwarding reference. Forwarding references bind to both lvalues and rvalues.
If you invoke foo
with an rvalue (e.g. foo(std::string{})
), then it will call the aforementioned overload.