参数包构造函数在类模板中隐藏用户定义的转换

Parameter pack constructor hiding user defined conversion in class template

本文关键字:用户 隐藏 定义 转换 构造函数 参数      更新时间:2023-10-16

我正在为数学向量编写一个简单的类模板。我在模板中有一个使用参数包的构造函数模板,以便可以使用可变数量的参数构造向量:

template <unsigned int N, typename T>
class Vec
{
public:
T m_components[N];
Vec()
: m_components{}
{ }
template<typename ...Args>
explicit Vec(Args... args)
: m_components{args...}
{ }
// ...
}

我还添加了用户定义的转换,以使用此模板在类之间进行转换:

// ...
template <unsigned int _N, typename _T>
explicit operator Vec<_N, _T> () const
{
Vec<_N, _T> vec;
for(unsigned int i = 0; i < N && i < _N; ++i)
vec.m_components[i] = static_cast<_T>(m_components[i]);
return vec;
}
// ...

但是,当我调用用户定义转换时,我是这样写的:

Vec<2, int> a(2, 8);
Vec<4, double> b;
b = (Vec<4, double>)a;

使用 C 样式转换的行会导致以下错误:

C2440: 'initializing': cannot convert from 'Vec<2, int>' to 'T' // points to the expansion of the parameter pack: m_components{args...}

当我单步执行代码时,我可以看到 C 样式强制转换直接进入参数包构造函数。为什么会这样,我做错了什么?如何防止参数包构造函数看似隐藏用户定义的转换?

添加此构造函数:

// ...
template <unsigned int _N, typename _T>
explicit Vec(const Vec<_N, _T>& other)
{
for(unsigned int i = 0; i < N && i < _N; ++i)
m_components[i] = static_cast<_T>(other.m_components[i]);
}
// ...

据我了解,我在这里可能大错特错(有更多专业知识的人可以更好地解释(,编译器不知道如何修改模板类的当前实例以便与另一个实例一起分配。

m_components在施工期间以固定大小分配。即使使用过载铸造操作员,您也只完成了一半的工作。必须有某种机制来修改当前实例,以接受来自另一个实例的数据。