I am refactoring our code-base, where I have the following code (simplified):
template <typename T>
class TVector3;
template <typename T>
class TVector4;
template <typename T>
struct TVector4
{
TVector3<T>& V3() { return (TVector3<T> &) *this; }
const TVector3<T>& V3() const { return (const TVector3<T> &) *this; }
};
template <typename T>
struct TVector3
{
template <typename U>
constexpr TVector3(const TVector4<U>& v) noexcept { }
};
typedef TVector3<float> Vec3f;
typedef TVector4<float> Vec4f;
struct RGBA
{
Vec4f rgba;
operator Vec3f() const { return rgba.V3(); }
};
clang warns me about returning reference to local temporary object (https://godbolt.org/z/ccxbjv771). Apparently (const TVector3<T> &) *this results in calling TVector3(const TVector4<U>& ), but why ?
Intuitively, I would have expected (const TVector3<T> &) to behave like reinterpret cast, or if at least the cast would have looked like (const TVector3<T>) *this (without &) it would kind of make sense to me that the compiler picked that constructor call for conversion.
Another simpler example:
#include <iostream>
struct A { };
struct B
{
B(const A& ) { std::cout << "B(const A&)" << std::endl; }
};
int main()
{
A a;
(const B&) a;
return 0;
}
It prints B(const A&) (https://godbolt.org/z/ocWjh1eb3), but why ? I am converting to const B& and not to B.