1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
#include <iostream>
#include <type_traits>
struct point { int x = 0 ; int y = 0 ; };
template < typename T > decltype(auto) to_pt( const T& arg )
{
if constexpr ( std::is_convertible_v<T,point> ) return arg ;
else return point{ arg->x, arg->y } ; // otherwise, expect pointer or smart pointer
}
template < typename T, typename U > point plus_xy( const T& a, const U& b )
{ return { to_pt(a).x + to_pt(b).x, to_pt(a).y + to_pt(b).y } ; }
int main()
{
const point a { 1, 12 } ;
struct point2 : point {};
const point2 b { { 3, 45 } } ;
struct smart_ptr { const point& p ; const point* operator->() const { return std::addressof(p) ; } };
const smart_ptr pa{a} ;
const smart_ptr pb{b} ;
for( auto[x,y] : { plus_xy(a,b), plus_xy(a,&b), plus_xy(a,pb), plus_xy(&a,pb), plus_xy(pa,pb) } )
std::cout << x << ", " << y << '\n' ;
}
|