# Different return types with same function

I'm implementing my own time unit class. This class provides a function for fetching a specific time value (milliseconds, seconds etc.). In order to prevent defining several get() functions for each time unit, I tried to implement a single function to serve this purpose.

typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long long u_ll;
typedef u_ll DAYS_DTYPE;
typedef u_char HOURS_DTYPE;
typedef u_char MINUTES_DTYPE;
typedef u_char SECONDS_DTYPE;
typedef u_short MILLISECONDS_DTYPE;

// used class members; max. values are handled class-internal
DAYS_DTYPE          m_days;         // max.: 18.446.744.073.709.551.615
HOURS_DTYPE         m_hours;        // max.: 23
MINUTES_DTYPE       m_minutes;      // max.: 59
SECONDS_DTYPE       m_seconds;      // max.: 59
MILLISECONDS_DTYPE  m_milliseconds; // max.: 999

// class-internal enum
enum TimeUnit { Milliseconds, Seconds, Minutes, Hours, Days };

// used member function
template <typename T>
T getTime(TimeUnit unit)
{
switch (unit)
{
case Milliseconds: return m_milliseconds;
case Seconds: return m_seconds;
case Minutes: return m_minutes;
case Hours: return m_hours;
case Days: return m_days;
default:
break;
}
}


In order to fetch a specific time unit I have to use sth. like this:

getTime<MILLISECONDS_DTYPE>(Time::Milliseconds))


Is this approach acceptable? In case it's not, what should I change?

• You might want to look closer at the std::chrono library. – Some programmer dude Apr 19 '15 at 9:16
• I don't think getTime<MILLISECONDS_DTYPE>(Time::Milliseconds)) is any better than getMillisec(). Actually it seems worse. So why do you want to just define a single function? – Lingxi Apr 19 '15 at 9:23
• @Lingxi To keep the amount of member functions as low as possible. But after all, it's not that minimalistic and clean as I thought. – neuronalbit Apr 19 '15 at 9:30

I prefer something like this, as its less to type and compile-time, you probably always know what kind of time you need on compile-time and even if not you can hack around that problem, so:

template<TimeUnit time>
struct TimeUnitImpl
{ using type = decltype(m_milliseconds); };

template<>
struct TimeUnitImpl<Seconds>
{ using type = decltype(m_seconds); };

template<>
struct TimeUnitImpl<Minutes>
{ using type = decltype(m_minutes); };

template<>
struct TimeUnitImpl<Hours>
{ using type = decltype(m_hours); };

template<>
struct TimeUnitImpl<Days>
{ using type = decltype(m_days); };

// used member function
template <TimeUnit unit = Seconds>
typename TimeUnitImpl<unit>::type getTime()
{
switch (unit)
{
case Milliseconds: return m_milliseconds;
case Seconds: return m_seconds;
case Minutes: return m_minutes;
case Hours: return m_hours;
case Days: return m_days;
default:
break;
}
}


In order to fetch a specific time unit you would have to use something like this:

getTime<Time::Milliseconds>()


Try it online!

In order to keep a "good style" I would change the function name here, too. Probably simply to time rather than getTime, that get-prefix is pretty much useless here.

But anyways, you might consider just using getTimeMilliseconds or something like that.

• So if my needed time unit differs from the default parameter list, I still have to use something like this: getTime<Time::Hours, HOURS_DTYPE>(). In the end there's not much difference in to used length at all. – neuronalbit Apr 19 '15 at 9:40
• I tested your code and implemented some basic checks for correct data type conversion, but as you can see here, some checks, beside of those for u_char of course, fail! – neuronalbit Apr 19 '15 at 9:59
• @NaCI thx, site was updating to slow :D – neuronalbit Apr 19 '15 at 10:03
• This is probably more typing then just writing separate getters, for both the class user and class writer. – T.C. Apr 19 '15 at 10:10
• @T.C. Thats why I suggested just using something like getTimeMilliseconds. – NaCl Apr 19 '15 at 10:10