【问题标题】:Parameter pack constructor hiding user defined conversion in class template参数包构造函数在类模板中隐藏用户定义的转换
【发布时间】:2020-02-08 00:51:35
【问题描述】:

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

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

【问题讨论】:

标签: c++ templates type-conversion variadic-templates parameter-pack


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

【讨论】:

    猜你喜欢
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 2015-05-05
    • 2021-08-31
    • 2012-08-14
    相关资源
    最近更新 更多