这个向量类在一个构造函数和一个所谓的“resize”运算符之间产生了混淆。resize运算符允许程序员将一个大小为n的向量转换成任意大小的向量。如果转换后的向量比基本向量拥有更多的元素,则用1进行填充。以下是实现的代码:
/*
* resize operator:
* T is the type of element the base vector holds
* N is the number of elements the base vector holds
* rN is the size of the new vector
*/
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;
}
向量类还具有类型安全的可变参数构造函数,可以接受任意数量和任意组合的元素(必须是类型T)和任意数量的向量(可以包含任意数量的元素,并且必须是类型T),只要添加到提供的向量中的裸元素的数量加上这些向量中的元素的数量等于构建向量包含的元素的数量,就可以。
因此,以下内容是有效的:
vec3 foo(vec2(1, 2), 3);
但不包括这个。
vec3 bar(vec4(1, 2, 3, 4), 5);
我通过计数器递归遍历所有元素,确保在编译时提供了正确数量的元素,然后使用静态断言来确保计数器最终达到向量所能容纳的元素数量。通常情况下,这样做效果很好,但以下代码除外:
vec4 bar(1, 2, 3, 4);
(vec3) bar; //PROBLEM HERE
问题在于C++认为(vec3)bar是要求可变参数构造函数,而实际上应该调用resize操作符。我尝试过将它们显式地声明,但没有成功。当我有了上面的代码时,如何确保C++使用resize运算符而不是可变参数构造函数?
简而言之,我如何告诉C++使用这个:
//resize operator
template<typename T, unsigned int N, unsigned int rN>
Vector<T, N>::operator Vector<T, rN>();
而不是这样:
//constructor
template<typename T, unsigned int N, typename ... Args>
Vector<T, N>::Vector(Args ... arguments);
当我有这段代码时:
(vec3) someVec4;
如果不太清楚,vec3和vec4的定义如下:
typedef Vector<float, 3> vec3;
typedef Vector<float, 4> vec4;
编辑:
大家好!有个消息要告诉大家,即使我使用 static_cast(someVec4),它仍然会调用使用 vec4 参数的 vec3 构造函数。我不知道为什么。
另一个编辑:
将构造函数设为显式可以让隐式转换起作用,但显式转换不行。也就是说,这段代码可以运行:vec3 foo = someVec4;
但是这段代码仍然会给我一个静态断言失败:
vec3 foo = static_cast<vec3>(someVec4);
这基本上没有意义,因为我已经声明了可变参数构造函数是显式的,所以不应该在那里被调用。
同时,根据请求,在此处提供 SSCCE
简而言之,我的代码在尝试显式调用类型转换运算符时调用了一个显式构造函数,但在尝试隐式调用它时却没有。
explicit
吗? - aschepler