运算符重载和不同的模板参数

用户名

我在重载operator + ia模板化类时遇到问题。假设我有

template<typename T>
struct point{

    //Ctors:
    point(){};
    point(T _x, T _y):x(_x),y(_y){};
    point(const point<T>& p):x(p.x),y(p.y){};

    template<typename T2>
    point(const point<T2>& p):x(static_cast<T>(p.x)),y(static_cast<T>(p.y)){};



   //Coordinates:
   T x;
   T y;


   //Operator overloads:
   friend point<T> operator+(point<T> left,point<T> right ){
       return point<T>(left.x+right.x, left.y+right.y);
   }

   template<class T2>
   friend point<T> operator+(point<T2> left,point<T> right){
       return point<T>(left)+right;

   }

   template<class T3>
   friend point<T> operator+(point<T> left,point<T3> right){
       return point<T>(right)+left;
   }


};

这给我打电话时的模棱两可的错误。

point<float> p1(1.2,1.4);
point<int> p2(1,2);    
point<float> p3 =p1+p2;    

这是有道理的,但是您能告诉我如何解决的好方法吗?

我需要3个运算符,因为否则转换可能会朝错误的方向进行。例如,忽略最后一个运算符重载将导致p3.x=2p3.y=4

非常感谢!

干杯和hth。-阿尔夫

在某种程度上,这是个人喜好和主观意见的问题,但是我想我会尝试为算术表达式的结果类型模拟普通的C ++规则,例如

template <class T1, class T2 >
friend
auto operator+( Point<T1> const left, Point<T2> const right )
    -> Point< decltype( left.x + right.x ) > 
{
    return {left.x + right.x, left.y + right.y};
}

满足g ++ 4.8.2和Visual c ++ 12.0都比我想象的要复杂,但是这里的具体代码可以使用这两个编译器进行干净地编译:

#include <type_traits>
#include <utility>

template< class Number >
struct Point
{
    Number  x;
    Number  y;
};

template< class T1, class T2 >
auto operator+( Point<T1> const left, Point<T2> const right )
    -> Point< typename std::remove_const<decltype( left.x + right.x )>::type > 
{
    using Result_number =
        typename std::remove_const<decltype( left.x + right.x )>::type;
    using Result_point = Point< Result_number >;
    return Result_point{ left.x + right.x, left.y + right.y };
}

auto main()
    -> int
{
    Point<float> const  p1{ 1.2, 1.4 };
    Point<int> const    p2{ 1, 2 };
    Point<float> const  p3 = p1 + p2;
}

为了促进可能的缩小转换,Point您可以添加一个显式的转换运算符成员函数,如下所示:

template< class Number >
struct Point
{
    Number  x;
    Number  y;

    template< class Other_number >
    explicit
    operator Point<Other_number>() const
    {
        return Point<Other_number>{
            static_cast<Other_number>( x ),
            static_cast<Other_number>( y )
            };
    }
};

要进行调用,请使用任何合适的强制转换,例如明显的构造函数表示法(具有上述定义的强制转换只是调用转换运算符的强制转换):

    Point<int> const    p4 = Point<int>( p1 + p2 );

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

运算符重载和不同的模板参数

来自分类Dev

复杂的运算符重载和模板

来自分类Dev

模板运算符重载

来自分类Dev

模板类运算符重载的不同错误和警告问题

来自分类Dev

通过运算符重载作为模板参数

来自分类Dev

类模板中的运算符重载和友谊

来自分类Dev

C ++模板类和运算符重载

来自分类Dev

重载++和+运算符

来自分类Dev

运算符重载传递和返回的参数

来自分类Dev

重载<<运算符的部分模板特化

来自分类Dev

模糊运算符<<用于模板重载

来自分类Dev

C ++:使用模板重载<<运算符

来自分类Dev

C ++:使模板运算符=重载朋友

来自分类Dev

运算符=模板类中的重载

来自分类Dev

C ++运算符重载模板类

来自分类Dev

模板类分配运算符重载

来自分类Dev

运算符重载VS模板功能

来自分类Dev

类模板的 constexpr 运算符重载

来自分类Dev

Java,运算符重载和String的“ +”运算符

来自分类Dev

模板中的二进制运算符重载以仅接受某些其他模板,从而正确处理不同的参数集

来自分类Dev

重载new和delete运算符

来自分类Dev

内联和运算符重载问题

来自分类Dev

+ =运算符重载和级联?

来自分类Dev

重载<<运算符,实现和分离

来自分类Dev

C ++赋值运算符和重载

来自分类Dev

协方差和运算符重载

来自分类Dev

在Dart中重载++和+ =运算符

来自分类Dev

虚拟重载运算符>>和<<

来自分类Dev

重载new和Delete运算符