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