我目前正在实现一个自定义字符串类,但我面临着类构造函数的一些问题。该类是 std::string 的自定义包装器,因此该类具有大多数 std::string 构造函数,但迭代器构造函数除外,因为运行代码的某些系统不支持 STL。
该类还提供了一些基于Arduino String实现的构造函数,特别是数字变量到字符串构造函数,如下所示:
数字转换构造函数:
// unsigned int
string(const uint8_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode);
string(const uint16_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode);
string(const uint32_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode);
string(const uint64_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode);
// signed int
string(const int8_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode, bool IntFormat = CPString::NumberConversion::IntFormat::Mode);
string(const int16_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode, bool IntFormat = CPString::NumberConversion::IntFormat::Mode);
string(const int32_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode, bool IntFormat = CPString::NumberConversion::IntFormat::Mode);
string(const int64_t Source, uint8_t Base = 10, bool LetterCase = CPString::NumberConversion::LetterCase::Mode, bool IntFormat = CPString::NumberConversion::IntFormat::Mode);
// float
explicit string(const float Source);
string(const float Source, uint8_t precision);
简单来说:Base 表示用于转换变量的基数,其中 2 为二进制,8 为八进制,16 为十六进制,可用的基数为 [2,32]。 LetterCase 是一个变量,定义是否应使用大写或小写字母。
问题是这组构造函数与 std::string 构造函数之一变得不明确,特别是填充构造函数(在定义下方):
string(unsigned int n, char c);
打电话时:
CPString::string myString(10,'a');
编译器抛出错误 C2666:重载函数具有类似的转换
我假设 char 文字被转换为 uint8_t,是否可以明确此构造函数?我知道将 10 更改为 10u 可以明确调用,但我想找到更好的解决方案。这也将接受 10 作为填充构造函数的第一个参数。
您面临的问题是固定宽度整数类型是别名,而不是单独的类型。通常,
uint8_t
只是 unsigned char
的另一个名称。不同的名称,而不是不同的类型。
将“数字转换构造函数”的第二个参数更改为大于
char
的值,例如 unit16_t
,应该可以解决歧义。
一个不同且更具可读性的解决方案是引入作用域枚举。例如:
enum class Base : uint8_t {
Base2 = 2,
Base3,
Base4,
Base5,
Base6,
// ...
// You get the idea, I hope
// ...
Base31,
Base32
};
此
Base
类型与所有其他类型不同,但其大小与 uint8_t
相同。使用它作为“数字转换构造函数”的第二个参数将使签名基本相同,但它们将不再含糊不清,并且调用站点将更容易阅读(Base16
更清楚地表示它是一个基础)比16
)。
您可以将参数类型设置为
auto
并使用 std::is_same<char&, decltype(parameter)>()
或 std::is_same<char, decltype(parameter)>()
表示 char,使用 std::is_same<uint8_t&, decltype(parameter)>()
或
std::is_same<uint8_t decltype(parameter)>()
用于无符号字符。
如果我错了请纠正我。