1

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

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 样式转换直接进入参数包构造函数。为什么会这样,我做错了什么?如何防止参数包构造函数看似隐藏用户定义的转换?

4

1 回答 1

1

添加此构造函数:

    // ...

    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期间分配了固定大小。即使使用重载强制转换运算符,您也只完成了一半的工作。必须有某种机制来修改当前实例,以便接受来自另一个实例的数据。

于 2020-02-08T01:21:20.747 回答