#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
const char*
隐式转换为 bool
而不是 std::string
,尽管构造函数需要 explicit
类型?因为
const char*
到bool
的隐式转换是标准转换,而const char*
到std::string
是自定义转换。前者排名更高,在 overload resolution. 中获胜
标准转换序列总是优于用户定义的转换序列或省略号转换序列。
BTW:
mystruct obj(c);
执行直接初始化,explicit
转换构造函数包括mystruct::mystruct(bool)
也被考虑。结果,c
被转换为 bool
然后传递给 mystruct::mystruct(bool)
作为构造 obj
. 的参数
直接初始化比复制初始化更宽松:复制初始化只考虑非显式构造函数和非显式用户定义的转换函数,而直接初始化考虑所有构造函数和所有用户定义的转换函数。
explicit
说明符,
- 指定构造函数
or conversion function (since C++11)
是显式的,也就是说,它不能用于 隐式转换 和 copy-initialization.or deduction guide (since C++17)
“为什么
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`
只是添加到已经很好的答案中。您可以通过添加 delegating constructor 来解决这个问题,如下所示:
mystruct(const char* s):mystruct(std::string(s)) {}
这将在重载决策中胜过 bool。
另一种选择是在这里避免使用 bool 并使用 bool 但具有更多含义的东西。这可能是'布尔盲目'
的一个例子