As the title says. C++ already has std::forward, but it can't cast the original type to another. I wonder if there is a function to cast one type to another while preserving the value category and cv-qualifers of the original type.
Supposing there is such a function called perfect_cast to do the magic, the output of the following code
#include <iostream>
#include <type_traits>
#include <format>
template <typename To, typename From>
decltype(auto) perfect_cast(From&& s)
{
// ???
}
template <std::size_t I>
struct A
{
void f()&
{
std::cout << std::format("lvalue A{:d}", I) << std::endl;
}
void f() const&
{
std::cout << std::format("const lvalue A{:d}", I) << std::endl;
}
void f()&&
{
std::cout << std::format("rvalue A{:d}", I) << std::endl;
}
void f() const&&
{
std::cout << std::format("const rvalue A{:d}", I) << std::endl;
}
};
template <std::size_t ...Is>
struct B : A<Is>... {};
auto g1()
{
return B<0, 1, 2, 3>{};
}
const auto g2()
{
return B<0, 1, 2, 3>{};
}
int main()
{
B<0, 1, 2, 3> b;
auto& b1 = b;
perfect_cast<A<0>>(b1).f();
const auto& b2 = b1;
perfect_cast<A<1>>(b2).f();
perfect_cast<A<2>>(g1()).f();
perfect_cast<A<3>>(g2()).f();
}
should be
lvalue A0
const lvalue A1
rvalue A2
const rvalue A3