I have a function that accepts an rvalue reference:
template<typename... Ts>
void foo(std::tuple<Ts...>&& t)
{
processFoo(std::forward<std::tuple<Ts...>>(t));
}
and another function that accepts an lvalue reference:
template<typename T>
void bar(const T& t);
I want bar
to be able to bind with both lvalues and rvalues, so it's signature is OK. Then, I want to call foo
with t
from bar. For this code:
template<typename T>
void bar(const T& t);
{
foo(t);
}
my compiler rightfully complains that there is no matching function for call to foo(...)
, as std::tuple<_blahblahblah>
and const std::tuple<_blah>
have incompatible cv-qualifiers. So I do the following:
template<typename T>
void bar(const T& t);
{
foo(std::forward<T>(const_cast<T&>(t)));
}
but the const_cast
looks like a workaround!
Does the above forwarding code look OK and idiomatic? Maybe it would be better to overload foo
for other reference types and cv-qualifiers? Or is there any "even more universal" reference, which would help to get rid of const_cast
?
This cannot work before
std::tuple<Ts...> &&
is not a forwarding reference, it is a simple rvalue-reference, and you cannot bind a const lvalue-ref to a rvalue-ref - Change your code to:And you will have a real forwarding reference, and your code will work.