为什么 const char* 隐式转换为 bool 而不是 std::string?

问题描述 投票:0回答:3
#include <iostream>
#include <string>

struct mystruct{
     mystruct(std::string s){
        
        std::cout<<__FUNCTION__ <<" String "<<s;
    }
    
     explicit mystruct(bool s) {
        
        std::cout<<__FUNCTION__<<" Bool "<<s;
    }
};


int main()
{
    
    const char* c ="hello";
    
    mystruct obj(c);

    return 0;
}

输出:

mystruct Bool 1
  1. 为什么
    const char*
    隐式转换为
    bool
    而不是
    std::string
    ,尽管构造函数需要
    explicit
    类型?
  2. 这里如何应用隐式转换优先级?
c++ implicit-conversion overload-resolution explicit constructor-overloading
3个回答
15
投票

因为

const char*
bool
的隐式转换是标准转换,而
const char*
std::string
是自定义转换。前者排名更高,在 overload resolution.

中获胜

标准转换序列总是优于用户定义的转换序列或省略号转换序列。

BTW:

mystruct obj(c);
执行直接初始化
explicit
转换构造函数包括
mystruct::mystruct(bool)
也被考虑。结果,
c
被转换为
bool
然后传递给
mystruct::mystruct(bool)
作为构造
obj
.

的参数

直接初始化比复制初始化更宽松:复制初始化只考虑非显式构造函数和非显式用户定义的转换函数,而直接初始化考虑所有构造函数和所有用户定义的转换函数。

关于

explicit
说明符,

  1. 指定构造函数
    or conversion function (since C++11)
    or deduction guide (since C++17)
    是显式的,也就是说,它不能用于 隐式转换copy-initialization.

1
投票

“为什么

const char*
隐式转换为
bool
而不是
std::string
,尽管构造函数需要
explicit
类型?”:

  • 标准转换优先于用户定义的转换。

char const*
是指向常量字符的指针,指针可以隐式转换为
bool
:如果它是
nullptr
,则转换为
false
,否则转换为
true

  • 您曾经在检查指针是否为

    NULL
    的情况下看到如此有效的转换,所以如果不是
    nulptr
    我们安全地取消引用它否则它具有
    nullptr
    值因此它是不正确的取消引用它:

    int* ptr = nullptr;
    
    if(ptr) // false  because ptr has nullptr or NULL or 0 or 0x000000 address value
       std::cout << ptr << '\t' << *ptr << '\n'; // not executed
    
    ptr = new int(10); // valid and non-nullptr
    
    if(ptr) // non-nullptr so condition succeeds
       std::cout << ptr << '\t' << *ptr << '\n'; // 0FED155   10
     delete ptr; // free memory
    
  • explicit
    构造函数意味着它只能被显式调用,唯一的方法是像你的情况一样通过直接初始化:

    mystruct obj(c); // direct initialization
    mystruct obj = c; // copy-initialization. Error: constructor myStruct(bool) is `explicit`
    

0
投票

只是添加到已经很好的答案中。您可以通过添加 delegating constructor 来解决这个问题,如下所示:

mystruct(const char* s):mystruct(std::string(s)) {}

这将在重载决策中胜过 bool。

另一种选择是在这里避免使用 bool 并使用 bool 但具有更多含义的东西。这可能是'布尔盲目'

的一个例子
© www.soinside.com 2019 - 2024. All rights reserved.