gartenriese
gartenriese

Reputation: 4356

Implementing km/h and m/s with user-defined literals

I want to implement two user-defined literals, _kmh for kilometers per hour and _ms for meters per second. I already have two structs for that and the operator "" functions:

constexpr KMH operator "" _ms(long double val) {
    return KMH {static_cast<double>(val * 3.6)};
}
constexpr MS operator "" _kmh(long double val) {
    return MS {static_cast<double>(val / 3.6)};
}

I want it to implement it in a way that I can could do something like this:

void func(MS speed) {}

int main() {
    func(10.0_kmh); // this works
    func(10.0_ms); // this does not
}

I can't get the second call to work, because I can't implement it like this:

constexpr KMH operator "" _kmh(long double val) {
    return KMH {static_cast<double>(val)};
}

This obviously gives me the error

error: functions that differ only in their return type cannot be overloaded

Is there a way to implement what I want?

Upvotes: 1

Views: 1354

Answers (2)

gartenriese
gartenriese

Reputation: 4356

As AProgrammer suggested, using only one basic struct for speed is a good solution.

struct speed {
    float m_val;
    constexpr speed(float val) : m_val{val} {}
    operator float() const { return m_val; }
};

constexpr speed operator "" _ms(long double val) {
    return speed {static_cast<float>(val)};
}
constexpr speed operator "" _kmh(long double val) {
    return speed {static_cast<float>(val) / 3.6f};
}

Upvotes: 1

Jarod42
Jarod42

Reputation: 217245

You may add non explicit operator MS()

class KMH
{
public:
    operator MS() const { return {val / 3.6}; }

// your previous stuff
};

or non explicit constructor in MS which take KMH

class MS
{
public:
    constexpr MS(const KMH& kmh) : val(kmh.val * 3.6) {}

// your previous stuff
};

BTW, you may stick with only one struct (MS) and make all your operator ""_ms, ""_kmh return MS

Upvotes: 2

Related Questions