【问题标题】:Constructor: is it the right one being called?构造函数:被调用的是正确的吗?
【发布时间】:2011-05-18 00:13:39
【问题描述】:

在你看来,哪个构造函数会被调用?

class Element {
public:
    Element(bool b = true, bool c = true);
    Element(const std::string s, bool b = true, bool c = true);
};
...
Element element("something", true);

错了!第一个。

我必须从头重新开始 Stroustrup 的书吗?

我尝试不使用 const,但没有任何变化。

看起来 char* 看起来更像 bool 而不是 std::string。

有了这段代码,一切都很好:

Element element(string("something"), true);

编译器:Microsoft Visual C++ 2010

操作系统:Windows 7

【问题讨论】:

  • 您似乎已经在编辑中回答了您自己的问题。这里有(另一个)真正的问题吗?
  • 旁注:请不要按值传递std::strings; const 引用在这里可能更有效。
  • tenfour:是的,我一开始使用的是 const 引用。我试图删除引用以查看情况是否有所改善。
  • Charles Bailey:好吧,我的答案不是。我想避免明确使用 string()。

标签: c++ string constructor boolean


【解决方案1】:

有一个从指针类型到bool的内置转换,非空指针转换为true,空指针值转换为false

std::string 是用户定义的类型(在用户一词的最宽松意义上),因此从 const char*std::string 的转换不会优于内置的 const char*bool转换。你必须这样做(或添加一个采用const char * 的重载)。

Element element( std::string("something"), true);

【讨论】:

  • 将第一个参数设为字符串引用不会有什么不同?
  • @Klaim:不,您仍然需要从 const char* 转换为 std:string,无论您是按值传递它还是将该临时值绑定到 const 参考参数。跨度>
  • 是的,我添加了一个需要 const char* 的重载,并且效果更好。谢谢。
【解决方案2】:

.

C++ 标准 (N1905) 说,

$4.1 标准转换是隐式的 为内置定义的转换 类型。第 4 条列举了完整的 一组这样的转换。一个标准 转换序列是一个序列 以下标准转换 顺序:

[...]

——零次或一次转换 以下套装:积分促销, 浮点提升,积分 转换,浮点数 转换,浮点积分 转化,指针转化, 指向成员转换的指​​针,和 布尔转换。

[...]

$4.4 一般而言,隐式 转换序列 (13.3.3.1) 由标准转换组成 序列后跟用户定义的 转换,然后是另一个 标准转换顺序。

4.12 布尔转换

$4.12.1 算术、枚举、 指针,或指向成员类型的指针可以转换为布尔类型的右值。零值,null 指针值,或空成员指针 值被转换为 false any 其他值转换为 true

13.3.3.2 对隐式转换序列进行排序

2 比较基本形式时 隐式转换序列(如 在 13.3.3.1 中定义)

——标准 转换序列 (13.3.3.1.1) 是 比a更好的转换顺序 用户定义的转换序列或 省略号转换序列,以及

——一个 用户定义的转换序列 (13.3.3.1.2) 是更好的转换 序列比省略号转换 序列(13.3.3.1.3)。

希望,它很好地解释了您的代码所显示的行为。 :-)

另外,这是一本好书:

Implicit conversion sequences (C++ only)

.

【讨论】:

  • 你真的应该引用 13.3.3.2 [over.ics.rank] 来解释为什么选择布尔转换而不是用户定义的转换序列。
  • @Charles 和@Nawaz:谢谢你们的回答。我将把 Charles 保留为被接受的版本,因为它更“实用”,但我很欣赏 Nawaz 暴露的理论方面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2021-11-10
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
相关资源
最近更新 更多