我正在通过“原理与实践使用C ++”这本书学习C ++,并对一个练习提出了疑问。它建议通过模板编写一个Number
类来保存一个数字并使其运算符超载。接下来,它建议使用一个也模板化的函数来求和不同类型的2个向量(int
+ double
或Number(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>>
的所有类型组合?
此外,对于这种过于复杂的解决方案,或者针对此类问题具有分离功能的解决方案是否更充分,编程实践更好?
编辑:减少代码以提高可读性
答案 0 :(得分:0)
为了更通用,您的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;
}