take a look at my code. It will convert Vector4 to Vector4. There is this copy constructor, which automatically does the conversion component by component. I can't understand one thing: why at the end of construction, when each component is correctly set up, default constructor is invoked on each component making output vector empty. You can see execution flow in the output below. Interesting is, that if I replace initialization list by 4 assignments, the code works as expected.
Compiler is VS2013.
#include <cstdio>
using namespace std;
struct half
{
unsigned short data;
half() : data(0) { printf("half::default_constructor\n"); }
half(half& pattern) : data(pattern.data) { printf("half::copy_constructor\n"); }
explicit half(float pattern) : data(16) { printf("half::from_float_constructor\n"); }
operator float() { printf("half::to_float_operator\n"); return 3.0f; }
};
template <typename T>
struct Vector4
{
Vector4() : x(0), y(0), z(0), w(0) { }
Vector4(T value) : x(value), y(value), z(value), w(value) { }
Vector4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) { }
template <typename U>
Vector4(Vector4<U>& other) : x((T)other.x), y((T)other.y), z((T)other.z), w((T)other.w) { }
union
{
struct { T x, y, z, w; };
struct { T r, g, b, a; };
};
};
int main()
{
Vector4<float> a(0, 1, 4, 6);
Vector4<half> b(a);
}
Output from this program:
half::from_float_constructor
half::to_float_operator
half::from_float_constructor
half::from_float_constructor
half::to_float_operator
half::from_float_constructor
half::from_float_constructor
half::to_float_operator
half::from_float_constructor
half::from_float_constructor
half::to_float_operator
half::from_float_constructor
half::default_constructor
half::default_constructor
half::default_constructor
half::default_constructor
The reason is that the code is invalid. You cannot store non-POD types in a union. Your code results in undefined behaviour. I don’t know exactly what the compiler does as a result, and why it invokes the default constructor1 – but that’s undefined behaviour for you.
1 Although I have a theory: it probably attempts to initialise r
, g
, b
and a
.