用typedef重载会导致错误
考虑以下几种类型:
#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名称因此是另一种类型的同义词。 typedef名称不会引入新类型(...)。
因此,这两个函数在输入参数的类型方面确实是模棱两可的。 您需要区分类型(例如,通过使用不同的类型,例如类或枚举),或者可能添加第二个参数(可能带有默认值),以指示正确传入哪种类型的类型。
链接到原来的答案:https://softwareengineering.stackexchange.com/questions/254473/in-which-stage-of-compilation-is-type-de-de- resolved-by-the-compiler
链接地址: http://www.djcxy.com/p/33717.html