0

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 ?

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

In other words i need to make foo(std::string &b) instead of foo(std::string &&b) and forget trying to get rvalues, basically forcing me to strictly only get lvalues ?
@AymenTM: possibly. I am not sure what your real use case is and what you're trying to achieve. But technically that would work.
Trying to have a template function do something for all types except for std::strings, I want it to do something specific. Ik about specializations but isn't this like the most specific ?
@AymenTM: you could use if constexpr + a type trait instead of relying on overloading.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.