gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 19:39:13 27 4
gpt4 key购买 nike

我在模板类中重载运算符+时遇到问题。假设我有

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 个运算符(operator),否则转换可能会走向错误的方向。例如,忽略最后一个运算符重载将导致 p3.x=2p3.y=4

非常感谢!

最佳答案

在某种程度上,这是个人喜好和主观意见的问题,但我认为我会尝试模拟算术表达式结果类型的普通 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 );

关于c++ - 运算符重载和不同的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23855474/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com