对类构造函数的不明确调用

问题描述 投票:0回答:2

我目前正在实现一个自定义字符串类,但我面临着类构造函数的一些问题。该类是 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 作为填充构造函数的第一个参数。

c++ constructor ambiguity
2个回答
0
投票

您面临的问题是固定宽度整数类型是别名,而不是单独的类型。通常,

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
)。


0
投票

您可以将参数类型设置为

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)>()
用于无符号字符。

如果我错了请纠正我。

© www.soinside.com 2019 - 2024. All rights reserved.