调用了错误的构造函数

Wrong constructor is being called

本文关键字:构造函数 错误 调用      更新时间:2023-10-16

我有一个创建不同种类变量的类。

通过一些宏定义,我们想要初始化这些变量。

#define NUMBER(number)      JsonVariable(number)
#define STRING(text)        JsonVariable(text)
#define TRUE                JsonVariable(true)
#define FALSE               JsonVariable(false)

数字初始化正常,但字符串调用 Bool 构造函数的原因未知。

JsonVariable(string x)
    : type(String), s(x)
{
    cout << "String" << x << endl;
    sleep
}
JsonVariable(bool x)
    : type(Boolean), b(x)
{
    cout << "Boolean" << x << endl;
    sleep
}

如果我注释掉 Bool 构造函数,则调用字符串构造函数。

有什么建议吗?

编辑:这是一个具有已定义宏的字符串构造函数。std::string 在构造函数中使用。

JSON(test) = STRING("Hello")

类型是定义的枚举。此外,宏必须用作此分配的一部分。

编辑2:为了澄清。下面是枚举类型。

std::string 与命名空间 std 一起使用,因此是单个字符串。字符串也来自枚举类型,所以

String != string
typedef enum {
    Null, Integer, Double, Boolean, String, Object, Array
} datatype;

您可能会遇到转换规则的影响。如果你传递了一个const char*bool重载优先于std::string&

void f(std::string&) { std::cout << "string"; }
void f(bool) { std::cout << "bool"; }
int main() {
    f("abc"); // prints 'bool'
}

这是合乎逻辑的:通常检查指针是否为非零,因此转换为 int/bool 类型是可取的。另一方面,绑定到const std::string&意味着std::string构造函数获取引用。在这里不可能绑定到std::string&,因为临时引用不会绑定到非常量引用。

解决方法是手动创建字符串,或者最好是使用 const char* 的构造函数。

根据经验,每当 API 公开此签名的重载函数或构造函数(或其 CV 限定和/或引用变体)时:

void func(std::string){}
void func(bool){}

您应该始终为const char*提供一个,

void func(std::string){}
void func(bool){}
void func(const char* c){ func(std::string(c)); }

否则,您和您的用户(尤其是)可能会遇到微妙的惊喜,因为:

字符串文字(例如"abc...")迅速衰减到const char*并且通过重载分辨率,转换为bool的优先级高于用户定义的转换,而用户定义的转换正是std::string所做的。