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=2
と、とになりp3.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とVisualC ++ 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]
コメントを追加