Конструктор пакета параметров, скрывающий определяемое пользователем преобразование в шаблоне класса

Я пишу простой шаблон класса для математических векторов. У меня есть в шаблоне шаблон конструктора с использованием пакета параметров, чтобы вектор можно было построить с переменным количеством параметров:

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 переходит прямо в конструктор пакета параметров. Почему это так и что я делаю не так? Как я могу запретить конструктору пакета параметров скрывать пользовательское преобразование?

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был выделен фиксированным размером при строительстве. Даже с оператором преобразования перегрузки вы сделали только половину работы. Должен существовать какой-то механизм для изменения текущего экземпляра таким образом, чтобы он принимал данные от другого.

Другие вопросы по тегам