通过类型检查实现 std::vector 的加法运算符
implementing addition operator for std::vector with type checking
这是我为 std::vector<T>
实现的 + operator
。
//+ operator overloading
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
它工作正常,大小异常在以下代码中也能正常工作。
//main function 1
std::vector<double> a,b,c;
a.assign(4,2);
b.assign(4,5);
try{
c = a+b;
}
catch(std::exception& e)
{
std::cout<<e.what();
return -1;
}
但我想在实现中添加一种类型检查,这样 +
操作将仅在大约 numerical types
(例如 int、double...)时被调用。
所以当我尝试+
关于std::vector<std::string>
的操作时,应该会发生异常。
但当前的实现没有。
//main function 2
std::vector<std::string> a,b,c;
a.assign(4,"this");
b.assign(4,"is awesome!");
try{
c = a+b;
}
catch(std::exception& e)
{
std::cout<<e.what();
return -1;
}
有什么办法吗?
谢谢。
你说:
But I want to add kind of type checking to implementation so that this +
operation will be invoked only about numerical types(eg. int
, double
...).
您可以添加一个static_assert
。
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
static_assert(std::is_arithmetic<T>::value, "Need arithmetic type");
看起来像是直接应用类型特征的案例:
#include <type_traits>
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
if (!std::is_arithmetic<T>::value)
{
throw std::exception("Only arithmetic vectors supported");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
由于 "being arithmetic" 是类型的编译时 属性,您可以更进一步,使用静态断言而不是异常来获得编译时错误而不是运行时错误:
#include <type_traits>
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
static_assert(std::is_arithmetic<T>::value, "Our vector operator + is intended for arithmetic types only");
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
然而,正如@chris 在评论中正确指出的那样:如果您想要动态大小的数值数组,您可能需要查看 std::valarray
.
这是我为 std::vector<T>
实现的 + operator
。
//+ operator overloading
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
它工作正常,大小异常在以下代码中也能正常工作。
//main function 1
std::vector<double> a,b,c;
a.assign(4,2);
b.assign(4,5);
try{
c = a+b;
}
catch(std::exception& e)
{
std::cout<<e.what();
return -1;
}
但我想在实现中添加一种类型检查,这样 +
操作将仅在大约 numerical types
(例如 int、double...)时被调用。
所以当我尝试+
关于std::vector<std::string>
的操作时,应该会发生异常。
但当前的实现没有。
//main function 2
std::vector<std::string> a,b,c;
a.assign(4,"this");
b.assign(4,"is awesome!");
try{
c = a+b;
}
catch(std::exception& e)
{
std::cout<<e.what();
return -1;
}
有什么办法吗?
谢谢。
你说:
But I want to add kind of type checking to implementation so that this
+
operation will be invoked only about numerical types(eg.int
,double
...).
您可以添加一个static_assert
。
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
static_assert(std::is_arithmetic<T>::value, "Need arithmetic type");
看起来像是直接应用类型特征的案例:
#include <type_traits>
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
if (!std::is_arithmetic<T>::value)
{
throw std::exception("Only arithmetic vectors supported");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
由于 "being arithmetic" 是类型的编译时 属性,您可以更进一步,使用静态断言而不是异常来获得编译时错误而不是运行时错误:
#include <type_traits>
template <typename T>
std::vector<T> operator+(std::vector<T> v1, const std::vector<T>& v2)
{
static_assert(std::is_arithmetic<T>::value, "Our vector operator + is intended for arithmetic types only");
if(v1.size() != v2.size())
{
throw std::exception("Two vector size must be same");
}
for(unsigned int i = 0; i<v1.size(); i++)
{
v1[i] += v2[i];
}
return v1;
}
然而,正如@chris 在评论中正确指出的那样:如果您想要动态大小的数值数组,您可能需要查看 std::valarray
.