我试图用模板(学习)实现一个简单的多维Point类。我需要两个专业化Point2D和Point3D-这是到目前为止我可以让构造函数像Point p(1、2)一样直接初始化Point的功能。尽管此代码可以编译并且可以正常工作,但我不喜欢的是专业化中的代码重复部分-我一定做错了。
我是C ++ /模板的新手-可以提供任何帮助。
#ifndef POINT_H_
#define POINT_H_
template< typename T, int Dimensions = 2 >
class Point
{
public:
typedef typename T value_type;
Point() { std::fill(elements_, elements_+Dimensions, 0); }
Point(const Point<T, Dimensions>& rhs) : elements_(rhs.elements_) {}
~Point() {}
Point & operator=(const Point<T, Dimensions>& rhs) { return *this; }
const Point operator+(const Point<T, Dimensions>& p)
{
Point<T, Dimensions> ret;
for(int i = 0; i < Dimensions; i++)
{
ret[i] += elements_[i] + p[i];
}
return ret;
}
Point & operator+=( const Point<T, Dimensions>& p)
{
for(int i = 0; i < Dimensions; i++)
{
elements_[i] += p[i];
}
return *this;
}
Point & operator-=( const Point<T, Dimensions> & p)
{
for(int i = 0; i < Dimensions; i++)
{
elements_[i] -= p[i];
}
return *this;
}
T & operator[](const size_t index)
{
return elements_[index];
}
private:
T elements_[Dimensions];
};
template<typename T>
class Point< T, 2 >
{
public:
Point(const T x, const T y)
{
elements_[0] = x;
elements_[1] = y;
}
typedef typename T value_type;
Point() { std::fill(elements_, elements_+Dimensions, 0); }
Point(const Point<T, 2>& rhs) : elements_(rhs.elements_) {}
~Point() {}
Point & operator=(const Point<T, 2>& rhs) { return *this; }
const Point operator+(const Point<T, 2>& p)
{
Point<T, 2> ret;
for(int i = 0; i < 2; i++)
{
ret[i] += elements_[i] + p[i];
}
return ret;
}
Point & operator+=( const Point<T, 2>& p)
{
for(int i = 0; i < 2; i++)
{
elements_[i] += p[i];
}
return *this;
}
Point & operator-=( const Point<T, 2> & p)
{
for(int i = 0; i < 2; i++)
{
elements_[i] -= p[i];
}
return *this;
}
T & operator[](const size_t index)
{
return elements_[index];
}
private:
T elements_[2];
};
template< typename T>
class Point< T, 3 >
{
public:
Point(const T x, const T y, const T z)
{
elements_[0] = x;
elements_[1] = y;
elements_[2] = z;
}
typedef typename T value_type;
Point() { std::fill(elements_, elements_+3, 0); }
Point(const Point<T, 3>& rhs) : elements_(rhs.elements_) {}
~Point() {}
Point & operator=(const Point<T, 3>& rhs) { return *this; }
const Point operator+(const Point<T, 3>& p)
{
Point<T, 3> ret;
for(int i = 0; i < 3; i++)
{
ret[i] += elements_[i] + p[i];
}
return ret;
}
Point & operator+=( const Point<T, 3>& p)
{
for(int i = 0; i < 3; i++)
{
elements_[i] += p[i];
}
return *this;
}
Point & operator-=( const Point<T, 3> & p)
{
for(int i = 0; i < 3; i++)
{
elements_[i] -= p[i];
}
return *this;
}
T & operator[](const size_t index)
{
return elements_[index];
}
private:
T elements_[3];
};
typedef Point< int, 2 > Point2Di;
typedef Point< int, 3 > Point3Di;
#endif //POINT_H_
最佳答案
您可以简单地在主模板中同时提供2D和3D构造函数。
这里没有必要与基类和其他Rube Goldberg solutions进行对合,因为没有要解决的问题:我们在模板领域,所有未使用的东西都只是未使用的。
例:
#ifndef POINT_H_
#define POINT_H_
#include <array> // std::array
#define STATIC_ASSERT( e ) static_assert( e, "!(" #e ")" )
template< typename T, int nDimensions = 2 >
class Point
{
private:
std::array< T, nDimensions > elements_;
public:
typedef T ValueType;
T& operator[]( int const i )
{
return elements_[i];
}
T const& operator[]( int const i ) const
{
return elements_[i];
}
void operator+=( Point const& other )
{
for( int i = 0; i < nDimensions; ++i )
{
elements_[i] += other.elements_[i];
}
}
void operator-=( Point const& other )
{
for( int i = 0; i < nDimensions; ++i )
{
elements_[i] -= other.elements_[i];
}
}
friend Point operator+( Point const& a, Point const& b )
{
Point ret( a );
ret += b;
return ret;
}
friend Point operator-( Point const&a, Point const& b )
{
Point ret( a );
ret -= b;
return ret;
}
Point(): elements_() {}
Point( int x, int y )
{
STATIC_ASSERT( nDimensions == 2 );
elements_[0] = x;
elements_[1] = y;
}
Point( int x, int y, int z )
{
STATIC_ASSERT( nDimensions == 3 );
elements_[0] = x;
elements_[1] = y;
elements_[2] = z;
}
};
typedef Point< int, 2 > Point2D;
typedef Point< int, 3 > Point3D;
#endif //POINT_H_
#include <iostream>
using namespace std;
wostream& operator<<( wostream& stream, Point3D const& point )
{
return (stream << "(" << point[0] << ", " << point[1] << ", " << point[2] << ")");
}
int main()
{
wcout << "starting" << endl;
Point3D a( 1, 2, 3 );
Point3D b( 4, 5, 6 );
a += b;
wcout << a << endl;
}
关于c++ - C++模板-简单点类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11891192/