调用了错误的构造函数

Posted

技术标签:

【中文标题】调用了错误的构造函数【英文标题】:Wrong constructor is being called 【发布时间】:2017-01-14 19:06:07 【问题描述】:

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

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

#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 构造函数,则调用 String 构造函数。

有什么建议吗?

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

JSON(test) = STRING("Hello")

Type 是一个已定义的枚举。宏也必须用作此分配的一部分。

EDIT2:为了澄清。这是枚举类型。

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

String != string

typedef enum 
    Null, Integer, Double, Boolean, String, Object, Array
 datatype;

【问题讨论】:

你是用真正的字符串还是const char*(比如"myString")来调用它? 这个JsonVariable(string x) : type(String), s(x) 编译吗? 除了你为什么使用 macors 祝你好运 - 考虑到海报使用 string 作为参数 我闭嘴——我的错 【参考方案1】:

您可能会体验到转换规则的影响。如果传递const char*,则bool 重载优先于std::string&amp;

void f(std::string&)  std::cout << "string"; 
void f(bool)  std::cout << "bool"; 

int main() 
    f("abc"); // prints 'bool'

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

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

【讨论】:

这里没有演员表。 @LightnessRacesinOrbit:谢谢,更正了术语(s/casting/conversion/)。 f("abc"); 永远不会调用 f(std::string&amp;),即使没有重载,因为您不能将临时绑定到非常量引用,您应该添加 const 感谢您的回复,但以上内容不适用于我的实施。 @Davelis4:到底是什么不起作用?添加一个接受const char*的构造函数?【参考方案2】:

根据经验,每当您的 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)); 

否则,您和您的用户(尤其是)可能会感到意外,因为:

string-literals(例如"abc...")迅速衰减到const char*,通过重载决议,转换到bool 的优先级高于用户定义的转换 em> 这就是 std::string 所做的。

【讨论】:

根据您的操作,您可能希望func(std::string) 改为通过.c_str() 调用func(const char*)。例如在 OP 的示例中,我认为不需要字符串构造。 这行得通,调用了 const char* 构造函数。但正如 Lightness 所提到的,这消除了对字符串构造的需要。谢谢。

以上是关于调用了错误的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

C++ 多级继承 - 调用基本构造函数错误

错误:在 C++ 中没有用于调用构造函数的匹配函数

为啥这段代码试图调用复制构造函数?

C++:在派生类构造函数中调用基类赋值运算符的错误形式?

处理类构造函数中的承诺错误[重复]