Задний план
Я реализую специальный контейнер для чисел.
template <typename T>
class VectorBase
{
// Some constructors...
friend VectorBase<T> operator+(const VectorBase& a, const VectorBase& b)
{
VectorBase<T> res;
// Addition...
return res;
}
// Additional non-trivial logic...
}
Затем он используется для различных типов, особенно для double и float:
typedef VectorBase<float> VectorFloat;
typedef VectorBase<double> VectorDouble;
Теперь я хотел бы использовать такую конструкцию
VectorFloat inFloat;
VectorDouble inDouble;
VectorDouble outDouble = inFloat + inDouble;
Где я хочу гарантировать, что операция сложения выполняется для double
объектов, а не для float
, чтобы избежать проблем с точностью. Точно так же, как это делается в выражениях на чистом C.
Один из способов добиться этого — сначала преобразовать объект VectorFloat
в VectorDouble
, а затем выполнить операцию сложения в «двойном мире». Это можно сделать вручную (назначив переменной с плавающей запятой временную двойную единицу) или автоматически компилятором во временную переменную. Насколько мне известно, для этого мне нужен параметрический конструктор или оператор присваивания для VectorDouble
, который принимает аргумент типа VectorFloat
и выполняет фактическое преобразование.
Вопрос
Можно ли добавить новый параметрический конструктор в специализацию шаблона без необходимости репликации всего кода шаблона для определенного параметра шаблона?
VectorBase<double>::VectorBase<double>(const VectorBase<float> &b) { ... }
Я знаю, что могу создать производный класс, который будет содержать необходимый параметрический конструктор, но это не сработает для меня, так как мне нужно позже вывести другой класс из VectorBase
, сохраняя при этом шаблон:
template<typename T>
class VerySpecialDerivedVector: public VectorBase<T> { ... };