【问题标题】:Implicitly casting to bool?隐式转换为布尔值?
【发布时间】:2014-04-16 05:26:22
【问题描述】:

我的代码出现了一个奇怪的问题,编译器似乎将我的参数隐式转换为另一种类型。但是,当我将构造函数标记为显式时,它似乎并没有解决问题。

我的单元测试中有这个

JsonValue stringItem("test");
CHECK(stringItem.type() == JsonValue::Type::String);

结果失败

4 == 3

这些是构造函数的样子...

JsonValue::JsonValue()
 : mType(Type::Null) {
}

JsonValue::JsonValue(bool ab)
 : mType(Type::Boolean) {
    mData.b = ab;
}

JsonValue::JsonValue(int ai)
 : mType(Type::Int) {
    mData.i = ai;
}

JsonValue::JsonValue(std::uint32_t aui)
 : mType(Type::UnsignedInt) {
    mData.ui = aui;
}

// It should be using this constructory
// but mType is not getting set to Type::String
JsonValue::JsonValue(const std::string &astr)
 : mType(Type::String) {
    mData.str = new std::string(astr);
}

正如我之前提到的,将JsonValue(bool) 标记为explicit 并不能解决问题。我还用-Wconversion 编译,没有警告

枚举看起来像这样

enum Type {
            Null = 0,
            Object,
            Array,
            String,
            Boolean,
            Int,
            UnsignedInt
         };

【问题讨论】:

  • 这有点奇怪..您确实在标题中添加了explicit 标签,而不是在构造函数主体中?为了更好的衡量,您可以发布一个完整的程序,以便我们可以原封不动地编译它吗?
  • 这是一个可运行的版本:ideone.com/qA6Whv
  • 我确实使用了一个名为 struct Bool 的轻量级包装器 bool 类型作为我的受歧视工会的成员。

标签: gcc c++11 casting implicit


【解决方案1】:

你需要明确构造函数的参数:

JsonValue stringItem(std::string("test"));

发生的情况是,您正在获得从 const char*bool 的隐式转换,因为这是内置类型之间的转换,并且比从 const char*std::string 的转换更匹配,这是一种涉及内置类型的转换。

或者,您可以添加一个构造函数,该构造函数采用const char* 并在内部存储一个字符串。这是一个更好的选择,因为它避免了您遇到的容易犯的错误:

JsonValue::JsonValue(const char* astr)
 : mType(Type::String) {
    mData.str = new std::string(astr);
}

请注意,从表面上看,这些似乎没有理由存储动态分配的字符串。这可能会增加不必要的复杂性。

【讨论】:

  • 不幸的是,由于 JsonValue 和 JsonObject/JsonArray 之间的循环依赖问题,我必须存储指针。我将数据存储在一个联合中
  • @rcapote 这可能是存储JsonArray 和/或JsonObject 指针、but storing std::string by value works just fine 的原因。
  • @Casey 好的,谢谢你的提示。少一件我必须跟踪的事情
  • @Casey 我仔细看了你的例子……::new (&mData.str) std::string(astr); 在做什么?以前从未见过这种结构
  • @rcapote "placement new" - 它在&mData.str 指向的内存中构造一个std::string。您可以跳过基本类型的构造,因为它们很简单,只需分配它们,就像在其他构造函数中所做的那样,但 std::string 具有非平凡的构造。我可以(并且可能应该)通过adding a string constructor to the union type instead 达到同样的效果。
猜你喜欢
  • 2018-01-03
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2014-09-07
相关资源
最近更新 更多