2015-06-29 81 views
0

我试图实现一个非常基本的Vector3Vec3)类。 我正在努力处理一个特例:Vec3<size_t>加上Vec3<int>成员函数的C++模板专门化

如何为这种情况制作模板专业化?

任何帮助,将不胜感激。 本

#include <array> 
#include <ostream> 
#include <vector> 

// #define Vec3f std::array<float, 3> 
// #define Vec3u std::array<size_t, 3> 

#define Vec3f Vec3<float> 
#define Vec3u Vec3<size_t> 
#define Vec3i Vec3<int> 

template <typename T> 
class Vec3 
{ 
    public: 
     Vec3(): _a() {} 
     Vec3(T x, T y, T z): _a({x, y, z}) {} 
     Vec3(const Vec3<T> & a): _a({a[0], a[1], a[2]}) {} 

     ~Vec3() {} 

     /// Print Vec3. 
     friend std::ostream & operator<<(std::ostream & os, const Vec3<T> & v) 
     { 
      os << "(" << v[0] << ", " << v[1] << ", " << v[2] << ")"; 
      return os; 
     } 

     inline typename std::array<T, 3>::reference operator[](size_t i) 
     { 
      return _a[i]; 
     } 

     inline typename std::array<T, 3>::const_reference operator[](size_t i) const 
     { 
      return _a[i]; 
     } 


     /// Test equality. 
     inline bool operator==(const Vec3<T> & other) const 
     { 
      bool a = abs(_a[0] - other._a[0]) < 1e-6; 
      bool b = abs(_a[1] - other._a[1]) < 1e-6; 
      bool c = abs(_a[2] - other._a[2]) < 1e-6; 
      return (a and b and c); 
     } 

     /// Test non-equality. 
     inline bool operator!=(const Vec3<T> & other) const 
     { 
      return not (*this == other); 
     } 


     /// Vec3 same type addition. 
     inline Vec3<T> operator+(const Vec3<T> & other) const 
     { 
      return {_a[0] + other[0], _a[1] + other[1], _a[2] + other[2]}; 
     } 


    protected: 
     std::array<T, 3> _a; 
}; 
+2

究竟是什么问题? – Petr

+0

作为仅供参考,您不需要在所有功能上使用内联。请参见:[是否在类定义中定义的C++成员函数中隐含“内联”)(http://stackoverflow.com/questions/9192077/is-inline-implicit-in-c-member-functions-defined-in-class-定义) – NathanOliver

+0

@NathanOliver。谢谢你的提示。 – blaurent

回答

3

你的问题是要找到size_tint之间的共同类型是结果的模板参数。 这是一个可能的解决方案:

/// Vec3 addition between vectors of different base type. 
template <class U> 
Vec3<typename std::common_type<T, U>::type> operator+(const Vec3<U> & other) const 
{ 
    return{ _a[0] + other[0], _a[1] + other[1], _a[2] + other[2] }; 
} 
+0

取决于预期的结果''可以使用'Vec3 ()+ declval ())>'而不是'common_type'('char + char'是'int',但它的通用类型是'char') – Jarod42

+0

@ Jarod42:感谢您的评论,这是我错过的观点。但是我发现了一些上下文,其中规则char + char-> int是可以的,因为它防止溢出(上下文是RGB像素,问题在于基于int的像素迟早会以某种方式转换回char版本) – marom

+0

谢谢你们的帮助。不幸的是,这并不像我想的那样严格。我希望**功能**可以添加'Vec3 '和'Vec3 '。例如,您的解决方案太过宽容,因为它们也实施Vec3 '和Vec3 '。 – blaurent