我目前正在编写库来处理我的研究领域的小数学向量和矩阵以及一些特殊功能。我目前正在测试一些 CRTP 技巧。以下代码在最后一行产生错误,我不知道为什么:
#include <iostream>
#include <initializer_list>
#include <type_traits>
// Abstract class
template<class TCRTP, class T, unsigned int TSIZE> class AbstractArray
{
// Constructor
public:
inline AbstractArray() : _data{}
{
std::cout<<"AbstractArray::AbstractArray()"<<std::endl;
}
// Copy constructor
public:
template<class TCRTP0, class T0> inline AbstractArray(const AbstractArray<TCRTP0, T0, TSIZE> &rhs)
{
std::cout<<"AbstractArray::AbstractArray(const AbstractArray<TCRTP0, T0, TSIZE> &rhs)"<<std::endl;
for(unsigned int i = 0; i < TSIZE; ++i) {
_data[i] = rhs[i];
}
}
// Initializer list constructor
public:
template<class T0> inline AbstractArray(const std::initializer_list<T0>& rhs)
{
std::cout<<"AbstractArray::AbstractArray(const std::initializer_list<T0>& rhs)"<<std::endl;
const T0* it = rhs.begin();
for (unsigned int i = 0; i < TSIZE; ++i) {
_data[i] = *it;
++it;
}
}
// Destructor
public:
inline ~AbstractArray()
{
std::cout<<"AbstractArray::~AbstractArray()"<<std::endl;
}
// Subscript operator
public:
inline const T& operator[](const unsigned int i) const
{
std::cout<<"AbstractArray::operator[](const unsigned int i) const"<<std::endl;
return _data[i];
}
inline T& operator[](const unsigned int i)
{
std::cout<<"AbstractArray::operator[](const unsigned int i)"<<std::endl;
return _data[i];
}
// Assignment operator
public:
template<class TCRTP0, class T0> inline AbstractArray<TCRTP, T, TSIZE>& operator=(const AbstractArray<TCRTP0, T0, TSIZE>& rhs)
{
std::cout<<"AbstractArray::operator=(const AbstractArray<TCRTP0, T0, TSIZE>& rhs)"<<std::endl;
for (unsigned int i = 0; i < TSIZE; ++i) {
_data[i] = rhs[i];
}
return *this;
}
// Sum assignment
public:
template<class TCRTP0, class T0> inline AbstractArray<TCRTP, T, TSIZE>& operator+=(const AbstractArray<TCRTP0, T0, TSIZE>& rhs)
{
std::cout<<"AbstractArray::operator+=(const AbstractArray<TCRTP0, T0, TSIZE>& rhs)"<<std::endl;
for (unsigned int i = 0; i < TSIZE; ++i) {
_data[i] += rhs[i];
}
return *this;
}
// Sum operator
public:
template<class T0> inline AbstractArray<TCRTP, typename std::common_type<T, T0>::type, TSIZE> operator+(const AbstractArray<TCRTP, T0, TSIZE>& rhs) const
{
return AbstractArray<TCRTP, typename std::common_type<T, T0>::type, TSIZE>(*this) += rhs;
}
// Data members
protected:
T _data[TSIZE];
};
// Array class
template<class T, unsigned int TSIZE> class NArray : public AbstractArray<NArray<T, TSIZE>, T, TSIZE>
{
// Constructor
public:
inline NArray() : AbstractArray<NArray<T, TSIZE>, T, TSIZE>()
{
std::cout<<"NArray::NArray()"<<std::endl;
}
// Copy constructor
public:
template<class TCRTP0, class T0> inline NArray(const AbstractArray<TCRTP0, T0, TSIZE> &rhs) : AbstractArray<NArray<T, TSIZE>, T, TSIZE>(rhs)
{
std::cout<<"NArray::NArray(const AbstractArray<TCRTP0, T0, TSIZE> &rhs)"<<std::endl;
}
// Initializer list constructor
public:
template<class T0> inline NArray(const std::initializer_list<T0>& rhs) : AbstractArray<NArray<T, TSIZE>, T, TSIZE>(rhs)
{
std::cout<<"NArray::NArray(const std::initializer_list<T0>& rhs)"<<std::endl;
}
// Destructor
public:
inline ~NArray()
{
std::cout<<"NArray::~NArray()"<<std::endl;
}
};
// Vector class
template<class T, unsigned int TSIZE> class NVector : public AbstractArray<NVector<T, TSIZE>, T, TSIZE>
{
// Constructor
public:
inline NVector() : AbstractArray<NVector<T, TSIZE>, T, TSIZE>()
{
std::cout<<"NVector::NVector()"<<std::endl;
}
// Copy constructor
public:
template<class TCRTP0, class T0> inline NVector(const AbstractArray<TCRTP0, T0, TSIZE> &rhs) : AbstractArray<NVector<T, TSIZE>, T, TSIZE>(rhs)
{
std::cout<<"NVector::NVector(const AbstractArray<TCRTP0, T0, TSIZE> &rhs)"<<std::endl;
}
// Initializer list constructor
public:
template<class T0> inline NVector(const std::initializer_list<T0>& rhs) : AbstractArray<NVector<T, TSIZE>, T, TSIZE>(rhs)
{
std::cout<<"NVector::NVector(const std::initializer_list<T0>& rhs)"<<std::endl;
}
// Destructor
public:
inline ~NVector()
{
std::cout<<"NVector::~NVector()"<<std::endl;
}
};
// Main
int main()
{
NArray<double, 3> a1({1., 2., 3.});
std::cout<<std::endl;
NArray<int, 3> a2({4., 5., 6.});
std::cout<<std::endl;
NArray<double, 3> a3({7., 8., 9.});
std::cout<<std::endl;
NVector<double, 3> v1({11., 12., 13.});
std::cout<<std::endl;
NVector<double, 3> v2({14., 15., 16.});
std::cout<<std::endl;
NVector<double, 3> v3({17., 18., 19.});
std::cout<<std::endl;
NVector<int, 3> v4({20., 21., 22.});
std::cout<<std::endl;
a1 = a2;
std::cout<<std::endl;
std::cout<<"TEST -> a1 = "<<a1[0]<<" "<<a1[1]<<" "<<a1[2]<<std::endl;
std::cout<<std::endl;
v1 = a2;
std::cout<<std::endl;
std::cout<<"TEST -> v1 = "<<v1[0]<<" "<<v1[1]<<" "<<v1[2]<<std::endl;
std::cout<<std::endl;
v1 += a2;
std::cout<<std::endl;
std::cout<<"TEST -> v1 = "<<v1[0]<<" "<<v1[1]<<" "<<v1[2]<<std::endl;
std::cout<<std::endl;
v1 = a3+a3;
std::cout<<std::endl;
std::cout<<"TEST -> v1 = "<<v1[0]<<" "<<v1[1]<<" "<<v1[2]<<std::endl;
std::cout<<std::endl;
//v2 = v3+v4; // <- This line does not work : "error : no match for "operator+" in "v3+v4"
std::cout<<std::endl;
return 0;
}
如何解决问题?还有一个问题要问专家:您认为这种编码运算符的方式是否有效,或者您是否考虑过一些可以提高代码质量的修改?在我开始使用 CRTP 修改我当前的实现之前,任何建议都将不胜感激。
非常感谢你 !