模板:如何泛化输入以接收整数、双精度或特定(模板)容器的向量

Templates: how to generalize input to receive vector of ints, doubles or specific (template) container?

本文关键字:模板 双精度 向量 何泛化 泛化 输入 整数      更新时间:2023-10-16

我正在通过《使用C++的原则与实践》一书来学习C++,并对一个练习有一个问题。它建议通过模板编写一个Number类来保存一个数字并重载其运算符。接下来,它建议使用一个同样模板化的函数来求和 2 个不同类型的向量(int + doubleNumber(int) + Number(double) )。

我当前的代码如下:

#include <iostream>
#include <vector>
using namespace std;
template<class T> class Number{
    T value;
public:
    Number() : value(T()) { }
    Number(T n) : value(n) { }
    Number(const Number& a) : value(a.value) { }
    T get() const {return value;};
};
template<class T, class U>
Number<typename std::common_type<T,U>::type>
operator+(const Number<T>& a, const Number<U>& b)
{
    return Number<typename std::common_type<T,U>::type>(a.get() + b.get());
}  
template<class T, class U>
Number<typename std::common_type<T,U>::type>
operator*(const Number<T>& a, const Number<U>& b)
{
    return Number<typename std::common_type<T,U>::type>(a.get() * b.get());
}        
template<class T, class U>
typename std::common_type<T,U>::type
sumProductOfVectors(vector<T>& vt, vector<U>& vu){
    typename std::common_type<T,U>::type sum = 0;
    if(vt.size() != vu.size() ) 
        return sum;
    for (int i = 0; i< vt.size(); i++)
    {
        sum += vt.at(i)*vu.at(i);
    }
    return sum;
}
int main(int argc, const char * argv[]) {
vector<Number<int>> vni;
vni.push_back(Number<int>(1));
vni.push_back(Number<int>(2));
vni.push_back(Number<int>(3));
vector<Number<double>> vnd;
vnd.push_back(Number<double>(1));
vnd.push_back(Number<double>(2));
vnd.push_back(Number<double>(3));
vector<int> vi = {1,2,3};
vector<double> vd = {1,2,3};
sumProductOfVectors<int,double>(vi,vd);
// sumProductOfVectors<int,double>(vni,vnd); // Does not accept
}

虽然对产品求和的函数适用于标准向量,但我很难让它也接受Numbers.在当前形式中,编译器指示对函数sumProductOfVectors的不匹配调用,当其中一个参数来自类 Number 时。

如何使它接受vector<int>vector<double>vector<Number<int>>vector<Number<double>>的所有类型的组合?

另外,对于

这种过于复杂的解决方案,还是为此类问题使用单独的函数会更合适并且是更好的编程实践?

编辑:减少代码以提高可读性

为了更通用,您的sumProductOfVectors可能如下所示:

template<class T, class U>
auto
sumProductOfVectors(const std::vector<T>& vt, const std::vector<U>& vu)
{
    decltype(vt[0] + vu[0]) sum{};
    if (vt.size() != vu.size()) {
        return sum;
    }
    // return std::inner_product(vt.begin(), vt.end(), vu.begin(), sum);
    for (std::size_t i = 0; i != vt.size(); ++i) {
        sum = sum + vt.at(i) * vu.at(i);
    }
    return sum;
}

演示