将转换构造函数添加到模板的特化

时间:2014-11-17 16:08:27

标签: c++ templates constructor template-specialization arithmetic-expressions

背景

我正在为数字实现一个专用容器。

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,然后在“双世界”中执行加法运算。这可以手动完成(将float变量分配给临时双精度变量)或由编译器自动完成。据我所知,要做到这一点,我需要在VectorDouble上有一个参数化构造函数或赋值运算符,它接受VectorFloat类型的参数并进行实际转换。

问题

是否可以将新的参数构造函数添加到模板的特化中,而无需复制特定模板参数的整个模板代码?

VectorBase<double>::VectorBase<double>(const VectorBase<float> &b) { ... }

我知道我可以创建一个派生类,它将包含所需的参数构造函数,但这对我不起作用,因为我需要稍后从VectorBase派生另一个类,同时仍然保持模板:

template<typename T>
class VerySpecialDerivedVector: public VectorBase<T> { ... };

1 个答案:

答案 0 :(得分:3)

可以使用SFINAE完成,例如:

template <typename T2,
    typename = typename std::enable_if<std::is_same<double, T>::value
                                       && std::is_same<float, T2>::value>::type>
VectorBase(const VectorBase<T2> &) { /* .. */ }

Live example

但我认为最好有:

template <typename T1, typenale T2>
friend VectorBase<typename std::common_type<T1, T2>::type>
operator+(const VectorBase<T1>& a, const VectorBase<T2>& b)
{
    using T = typename std::common_type<T1, T2>::type;
    VectorBase<T> res;
    // Addition...
    return res;
}