Michael Michael - 1 year ago 44
C++ Question

Extending type conversion to pairs/tuples of convertable types

I've got to deal with a bunch of 2D point types:

, and I'd like to allow implicit conversions between points whenever there exists a conversion of their coordinates. Something like this:

template< class From, class To >
inline operator pair< To, To > ( pair< From, From > that )
return make_pair( static_cast< To >( that.first ),
static_cast< To >( that.second ) );


convert.cpp:5: error: ‘operator std::pair(std::pair)’ must be a nonstatic member function

Is it possible to do the above w/out defining wrapper classes for the

Answer Source

You cannot make implicit conversion to an unknown type; and again, conversion operator must be a non-static member function which will still require you to wrap it a class; and write a converting constructor from an unknown type (aka templated constructor).

Why don't you want to make it a free function:

template<typename To, typename From>
std::pair<To, To> convert(const std::pair<From, From>& p){
    return std::make_pair( static_cast< To >( p.first ), 
                static_cast< To >( p.second ) );

And then call it like:

std::pair<float, float> mp{3.424, 59.35};
auto p2 = convert<double>(mp);

That's just about as clear as it can be. See it Live on Coliru

(As per OP's comment):

You could do a quick Type for that sort of thing:

template<typename T>
class Point{
    T x = T{};
    T y = T{};

    template<typename Y>
    Point(Point<Y> p) : 
    { }

    Point(T x_val, T y_val) : x(x_val), y(y_val)
    { }

    Point(Point&&) = default;
    Point(const Point&) = default;
    Point& operator = (Point&&) = default;
    Point& operator = (const Point&) = default;

Consider this function that uses a double as the type parameter to Point:

void print(Point<double> p){
    std::cout << "(" << p.x << ", " << p.y << ")\n";

The statements below will all work because of the Converting constructor.

int main() {
    Point<float> mp{4.535, 395.3};
    Point<int> ip = mp;
    return 0;

See it Live on Coliru