用 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 或枚举)或者可能添加第二个参数(可能具有默认值)以指示正在传入的类型。
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
考虑以下类型:
#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 或枚举)或者可能添加第二个参数(可能具有默认值)以指示正在传入的类型。
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