【问题标题】:Why is a const pointer accidentally converted to bool? [duplicate]为什么 const 指针意外转换为 bool? [复制]
【发布时间】:2019-12-18 00:06:03
【问题描述】:

我有一个有两个构造函数的类。一种用于bool,一种用于A*

struct B
{
    explicit B(bool b)
    {
      std::cout << "B(bool)" << std::endl;
    }
    explicit B(A*)
    {
      std::cout << "B(A*)" << std::endl;
    }
};

当 B 应该使用 const A* 而不是 A* 构造时 -- const A* 被转换为 bool

const A a;
B b(&a);

输出:B(bool)


理想的解决方案是

编译器错误:“B(const A*) 没有有效的构造函数”

我已经尝试过使用explicit 关键字,但它不起作用。

running example at coliru

【问题讨论】:

  • 如果你把B(bool)改成B(bool&amp;)也可以解决问题。或者考虑使用duplicate answer 中所述的 type_trait。
  • 谢谢——现在我需要在我们的代码库中找到所有可能的“陷阱”
  • 我认为这不是重复的 - 建议的重复有 std::string 重载。这是非常不同的——字符串不是内置类型,也不会转换为bool。指针可以。
  • @MSalters,这似乎是重复的,因为在链接的 Qn 中,OP 期望 const char* 转换为 std::string。这里是const A*。您也可以将超级副本引用到链接的 Qn。请参阅 OP 的 comment,它表明链接的答案满足查询。
  • 完全 - 对我来说,可以使用链接的问题 - 似乎没有比链接的答案和@songyuanyao 提到的更好的解决方案。

标签: c++ casting compiler-errors boolean-expression


【解决方案1】:

我们无法停止从指针到bool 的隐式转换(bool conversion);您可以添加另一个采用const A* 的重载构造函数,在传递const A* 时将在overload resolution 中选择它,因为它是完全匹配的,而B::B(bool) 需要隐式转换。将其标记为 delete 后,如果选择该程序,则该程序将变为格式错误。

struct B
{
    explicit B(bool b)
    {
      std::cout << "B(bool)" << std::endl;
    }
    explicit B(A*)
    {
      std::cout << "B(A*)" << std::endl;
    }
    B(const A*) = delete;
};

LIVE

或者你可以将重载的构造函数标记为指针类型delete,然后所有指针类型都不能传递给B::B,除了A*,它的构造函数像你所做的那样单独声明。

template <typename T>
B(T*) = delete;

LIVE

【讨论】:

  • 可能——但是否还有一个解决方案可以让我不会意外忘记所有可能的重载?
  • @florgeng 答案已修改。这就是你想要的吗?
  • 是的,链接的答案适合我的问题——不幸的是——还是谢谢你
  • 通过解释重载决议和隐式转换序列来扩展这个答案可能很有用。
  • 你还需要explicit B(std::nullptr_t) : B((A*)nullptr) {}。 ;-)
猜你喜欢
  • 1970-01-01
  • 2021-11-29
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 2013-10-20
  • 2011-01-14
相关资源
最近更新 更多