繁体   English   中英

使用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的别名。

AFAIK唯一的解决方案是提供单独的方法:

std::string toClockString(clockval_t);

或使它成为一个对象:

class clockval ...

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

即使有一种方法可以让编译器选择正确的版本,你是否意识到它会如何容易出错? 幸运的是,没有这种方法,因为typedef创建了别名,仅此而已。

我建议你把它转换成课堂。 如果你提供了正确的构造函数和转换操作符,那么你甚至不需要更改使用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

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

是的,你是对的,你不能在typedef重载,因为它只是一个别名。 正如您所建议的那样,重命名函数或使用class创建新类型。 简单地添加一个参数来改变函数签名通常是一个坏主意,重命名更清晰。

typedef的含义在标准中定义为(7.1.3 typedef说明符):

在其声明的范围内,typedef-name在语法上等同于关键字,并命名与标识符(...)关联的类型。 因此,typedef-name是另一种类型的同义词。 typedef-name不引入新类型(...)。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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