简体   繁体   中英

overload with typedef gives an error

Consider the following types:

#include <iostream>

typedef unsigned long long      usize_t;
typedef unsigned __int16        uword_t;
typedef uword_t                 clockval_t;     // time without seconds in format HHMM

std::string toString(clockval_t nClock)
{
    return std::to_string((usize_t)nClock/100) + ":" + std::to_string((usize_t)nClock % 100);
}

std::string toString(uword_t nValue)
{
    return std::to_string((usize_t)nValue);
}

void test(void)
{
    uword_t val = 1;
    clockval_t time = 1023; // 10:23

    std::cout << "Value: " << toString(val);
    std::cout << "time: " << toString(time);
}

Now when I try to compile this, I get an error from the compiler telling me that the std::string toString(clockval_t) already has a body. I understand why this happens of course, because the typedef is just an alias for uword_t .

AFAIK the only solutions are to provide a separate method:

std::string toClockString(clockval_t);

or make it an object:

class clockval ...

Is this correct or is there some other way to make the compiler choose the correct overload?

Even if there were a way to make compiler choose correct version, do you realize how it would be error-prone? Luckily, there is no such way because typedef creates alias and nothing more.

I suggest that you convert it into class. If you provide proper constructor and conversion operator then you even don't need to change parts of code which make use of clockval_t :

class clockval_t {
public:
  clockval_t(uword_t aValue) : value(aValue) {}
  operator uword_t() const { return value; }

private:
  uword_t value;
};

...

clockval_t time = 1023; // works fine
std::cout << time << std::endl; // works fine
std::cout << (time / 10) << std::endl; // works fine

Is this correct or is there some other way to make the compiler choose the correct overload?

Yes you're correct, you can't overload on typedef since it's simply an alias. As you rightly suggest, either rename the function or create a new type with class . Adding a fake parameter simply to change the function signature is usually a bad idea, renaming is clearer.

The meaning of typedef is defined in the standard as (7.1.3 The typedef specifier):

Within the scope of its declaration, a typedef-name is syntactically equivalent to a keyword and names the type associated with the identifier (...). A typedef-name is thus a synonym for another type. A typedef-name does not introduce a new type (...).

Therefore the two functions are indeed ambiguous in regard to the type of input parameter. You need to distinguish the type (eg by using different type, eg a class or enum) or perhaps add a second parameter (maybe with a default value) indicating which kind type exactly is being passed in.

Link to original answer: https://softwareengineering.stackexchange.com/questions/254473/in-which-stage-of-compilation-is-typedef-resolved-by-the-compiler

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM