用 typedef 重载会报错

overload with typedef gives an error

考虑以下类型:

#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);
}

现在,当我尝试编译它时,编译器提示我 std::string toString(clockval_t) 已经有主体。我当然理解为什么会发生这种情况,因为 typedef 只是 uword_t.

的别名

据我所知,唯一的解决方案是提供一个单独的方法:

std::string toClockString(clockval_t);

或将其设为对象:

class clockval ...

这是正确的还是有其他方法让编译器选择正确的重载?

typedef的含义在标准中定义为(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 (...).

因此这两个函数在输入参数的类型上确实有歧义。您需要区分类型(例如,通过使用不同的类型,例如 class 或枚举)或者可能添加第二个参数(可能具有默认值)以指示正在传入的类型。

Link 原答案:https://softwareengineering.stackexchange.com/questions/254473/in-which-stage-of-compilation-is-typedef-resolved-by-the-compiler

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

是的,你是对的,你不能在 typedef 上超载,因为它只是一个别名。正如您正确建议的那样,要么重命名该函数,要么使用 class 创建一个新类型。添加一个 fake 参数只是为了改变函数签名通常不是一个好主意,重命名更清楚。

即使有办法让编译器选择正确的版本,你知道它有多容易出错吗?幸运的是,没有这样的方法,因为 typedef 创建了别名,仅此而已。

我建议你把它转换成class。如果您提供适当的构造函数和转换运算符,那么您甚至不需要更改使用 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