0

For now, user-defined literals accept a limited set of types as input parameter (see here). Is there any plan to accept any type as input parameter, and if not why is that ?

For example, I might want to be able to get a std::chrono::duration in different format (seconds, milliseconds, etc), and would do something like

constexpr double operator"" _s(std::chrono::nanosecond time)
{
   return std::chrono::duration_cast<std::chrono::duration<double, std::chrono::seconds::period>>(time).count();
}

constexpr long operator"" _us(std::chrono::nanoseconds time)
{
    return std::chrono::duration_cast<std::chrono::microseconds>(time).count();
}

// And so on ...

int main()
{
    auto t0 = std::chrono::high_resolution_clock::now();
    // do some stuff
    auto t1 = std::chrono::high_resolution_clock::now();

    std::cout << "Time in seconds : " << (t1 - t0)_s << "s\n";
    std::cout << "Time in microseconds : " << (t1 - t0)_us << "µs\n";

    return 0;
}
cmourglia
  • 2,423
  • 1
  • 17
  • 33
  • 9
    That wouldn't work anyway since `(t1 - t0)` is not a literal expression. In short, user-define literals will not have any other arguments because then they will not be *literals* any more. – Some programmer dude Nov 14 '16 at 15:02
  • The wording is indeed incorrect, I have more some type of "postfix function" in mind, not sure how to call it though. – cmourglia Nov 14 '16 at 15:25
  • 1
    @Zouch What advantage would `(t1 - t0)_s` have over `std::chrono::duration(t1 - t0)`? If it's merely the number of characters a `using` could take care of that. – Biffen Nov 14 '16 at 15:35
  • I feel like for manipulating things like SI units and conversions between them, it makes code more natural to read and write – cmourglia Nov 14 '16 at 15:39

1 Answers1

0

Maybe you could make use of helper structs instead:

#include <chrono>
#include <iostream>

using namespace std::literals::chrono_literals;

template <class Duration>
struct dc {
    using rep = typename Duration::rep;
    const std::chrono::nanoseconds time;
    constexpr dc(std::chrono::nanoseconds time):time(time) { }
    constexpr operator rep() {
       return std::chrono::duration_cast<Duration>(time).count();
    }
};

using s_ = dc<std::chrono::seconds>;
using us_ = dc<std::chrono::microseconds>;

// And so on ...

template <us_::rep N>
struct S {
};

int main()
{
    auto t0 = std::chrono::high_resolution_clock::now();
    // do some stuff
    auto t1 = std::chrono::high_resolution_clock::now();
    std::cout << "Time in seconds : " << s_(t1 - t0) << "s\n";
    std::cout << "Time in microseconds : " << us_(t1 - t0) << "µs\n";
    S<us_(10us)> us;
    (void)us;
    return 0;
}

[live demo]

W.F.
  • 13,888
  • 2
  • 34
  • 81
  • 3
    First, sprinkle some `const`. Second, that can be made into a template + typedefs. Third, use the duration's `rep_type` rather than hard-coded `int`. – T.C. Nov 14 '16 at 19:17
  • Good advice, Thanks! – W.F. Nov 14 '16 at 19:56