Suppose somewhere in my code is a function foo
with a universal reference parameter, which I cannot change:
template<typename T>
auto foo(T&& t) { std::cout<<"general version"<<std::endl; }
Now I want to overload foo
for a given class A
, and make sure that for any qualifier and reference type of A
the overload is called. For this I can brute-forcely provide an overload for all possible qualifications (ignore volatile
for now):
auto foo(A & a) { std::cout<<"A&"<<std::endl; }
auto foo(A const& a) { std::cout<<"A const&"<<std::endl; }
auto foo(A && a) { std::cout<<"A &&"<<std::endl; }
auto foo(A const&& a) { std::cout<<"A const&&"<<std::endl; }
Demo. This however scales very badly for more parameters.
Alternatively, I can pass by value, which seems to capture as well all the previous cases:
auto foo(A a) { std::cout<<"A"<<std::endl; }
Demo. Now however large object need to be copied (--at least in principle).
Is there an elegant way around these problems?
Remember that I can't change the universal reference function, so SFINAE and the like is no possibility.
operator&&
(I just tookfoo
as a simple example). It's a library and that is too erroneous. – Mottstd::enable_if
constraints or similar. Fortunately Concepts will have ordered constraints to solve this issue :). – OrthoepyA
within the function? Say, construct a copy of it? It is somewhat rare you want to both consume an rvalue ref and a non-const lvalue ref, unless you are doing something like creating a copy. – Silverpointstd::move
it further. In this way only the position of the copy is moved. – Mott