C ++ (more specifically, the MinGW g ++ implementation) gets confused. I have a math vector class that contains an arbitrary number of an arbitrary element type. The type of element and the number of elements are indicated at compile time.
The Vector class is confused between one of its constructors and what I dubbed the "resize" operator. The resize operator allows the programmer to overlay a vector of one size into a vector of another arbitrary size. If the translation vector has more elements than the base vector, it fills 1. Here's the implementation:
template<typename T, unsigned int N, unsigned int rN> operator Vector<T, rN>() const { Vector<T, rN> resize; for (unsigned int i = 0; i < rN; i++) { resize[i] = i < N ? this->elements[i] : 1; } return resize; }
The vector class also has a type-safe constructor of variations, which can take any number of any combination of elements (which must be of type T) and any number of vectors (which can contain any number of elements and must be of type T) as long as the number of elements added to the number of elements in the delivered vectors is equal to the number of elements that the construction vector contains.
Thus, this will be true:
vec3 foo(vec2(1, 2), 3);
but not that.
vec3 bar(vec4(1, 2, 3, 4), 5);
I guarantee that the correct number of elements was provided at compile time, recursing everything through them with a counter, then I use a static statement to make sure that the counter ends with the number of elements that the vector can contain. This works fine except for the following code:
vec4 bar(1, 2, 3, 4); (vec3) bar;
What happens is that C ++ believes that the (vec3) bar requests a variable constructor when in fact it should call the resize operator. I tried to make them explicit, but that didn't work. How can I guarantee that C ++ uses the resize operator when I have the code above and not the Variadic constructor?
In short, how can I tell C ++ to use this:
//resize operator template<typename T, unsigned int N, unsigned int rN> Vector<T, N>::operator Vector<T, rN>();
instead of this:
//constructor template<typename T, unsigned int N, typename ... Args> Vector<T, N>::Vector(Args ... arguments);
when i have this code:
(vec3) someVec4;
If this is unclear, vec3 and vec4 are defined as such:
typedef Vector<float, 3> vec3; typedef Vector<float, 4> vec4;
EDIT :
News, everything! Even when I use static_cast (someVec4), it still calls the vec3 constructor with the vec4 argument. I do not know why.
OTHER CHANGE :
Creating an explicit constructor allows implicit responses to work, but not explicit ones. This means that this code works:
vec3 foo = someVec4;
But this code still gives me a static rejection statement:
vec3 foo = static_cast<vec3>(someVec4);
Which basically makes no sense, because I declared the varadic constructor explicit, and therefore should not be called there.
Also on request here SSCCE
TL version; DR is that my code invokes an explicit constructor when I try to explicitly call the typecasting operator, but not when I try to implicitly call it.