Michael
Michael

Reputation: 5897

Extending type conversion to pairs/tuples of convertable types

I've got to deal with a bunch of 2D point types: pair<double>, pair<float>, pair<int>, 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 ) );
}

Unfortunately, g++ objects:

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 pairs?

Upvotes: 1

Views: 1054

Answers (1)

WhiZTiM
WhiZTiM

Reputation: 21576

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

EDIT
(As per OP's comment):

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

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

    template<typename Y>
    Point(Point<Y> p) : 
        x(static_cast<T>(p.x)),
        y(static_cast<T>(p.y))
    { }

    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;
    print(mp);
    print(ip);
    return 0;
}

See it Live on Coliru

Upvotes: 1

Related Questions