C ++, std :: swap overload, compiler error, VS 2010

I would like to overload std :: swap in my template class. In the following code (simplified)

#ifndef Point2D_H #define Point2D_H template <class T> class Point2D { protected: T x; T y; public: Point2D () : x ( 0 ), y ( 0 ) {} Point2D( const T &x_, const T &y_ ) : x ( x_ ), y ( y_ ) {} .... public: void swap ( Point2D <T> &p ); }; template <class T> inline void swap ( Point2D <T> &p1, Point2D <T> &p2 ) { p1.swap ( p2 ); } namespace std { template <class T> inline void swap ( Point2D <T> &p1, Point2D <T> &p2 ) { p1.swap ( p2 ); } } template <class T> void Point2D <T>::swap ( Point2D <T> &p ) { using (std::swap); swap ( x, px ); swap ( y, py ); } #endif 

there is a compiler error (only in VS 2010):

 error C2668: 'std::swap' : ambiguous call to overloaded 

I don’t know why, std :: swap should be overloaded ... Using g ++ code works fine. Without templates (i.e. Point2D is not a template class) this code also works.

Thank you for your help.

+4
source share
3 answers

See How to overload std :: swap () . Basically, you are allowed to specialize std :: swap, but not overload.

So, it’s quite normal to create a specific version for a specific type of Point<> (say Point<float> ), but not for any Point<T> .

+5
source

I know you didn’t ask this, but since you are using VC10, providing the constructor move and the assignment operator < , you should do std::swap() for your type.

+2
source

The reason it is ambiguous is because you provided :: swap and std :: swap, then you using 'd std :: swap. You now have :: swap and std :: swap in the global namespace. Therefore, the compiler does not know if you mean: swap or std :: swap.

However, providing a move / constructor statement will make swap work optimally, realistically.

0
source

Source: https://habr.com/ru/post/1334010/


All Articles