为什么我可以将 0 转换为 std::shared_ptr<T> 而不是 1?
Why can I convert 0 to an std::shared_ptr<T> but not 1?
#include <memory>
void f1(std::shared_ptr<bool> ptr) {}
int main() {
f1(0); // OK
f1(1); // compilation error: could not convert ‘1’ from ‘int’ to ‘std::shared_ptr<bool>’
}
都是int
,为什么0
但是1
可以转换成std::shared_ptr<T>
?
如何检查编译时1
到std::shared_ptr<T>
的转换是否失效?
编译时如何检查1
到std::nullptr_t
转换不准?
0
是C/C++中的一个特殊值。许多事情适用于 0
但不适用于 1
。原因是语言的转换规则。
f1(0); // OK
没关系,因为有以下转换。
0 -> nullptr
nullptr -> std::shared_ptr<bool> // Through a constructor
然而,
f1(1);
不行,因为没有可用于将 1
转换为 shared_ptr<bool>
的转换。
std::shared_ptr<T>
有一个采用 std::nullptr_t
的构造函数,其中存在从任何有效的空指针常量(包括普通 0
文字)的隐式转换。另一方面,1
不是任何 shared_ptr
构造函数的有效参数。
除了其他答案之外,一种解决方法是改用 std::make_shared 宏:
f1(std::make_shared<bool>(0)); // OK
f1(std::make_shared<bool>(1)); // OK
这样您就可以向函数提供任何整数文字。简单的工作示例:
#include <iostream>
#include <memory>
void f1(std::shared_ptr<bool> ptr) {
std::cout << std::boolalpha << *ptr << '\n';
}
int main() {
f1(std::make_shared<bool>(0)); // OK
f1(std::make_shared<bool>(1)); // OK
f1(std::make_shared<bool>(2)); // OK
}
#include <memory>
void f1(std::shared_ptr<bool> ptr) {}
int main() {
f1(0); // OK
f1(1); // compilation error: could not convert ‘1’ from ‘int’ to ‘std::shared_ptr<bool>’
}
都是int
,为什么0
但是1
可以转换成std::shared_ptr<T>
?
如何检查编译时1
到std::shared_ptr<T>
的转换是否失效?
编译时如何检查1
到std::nullptr_t
转换不准?
0
是C/C++中的一个特殊值。许多事情适用于 0
但不适用于 1
。原因是语言的转换规则。
f1(0); // OK
没关系,因为有以下转换。
0 -> nullptr
nullptr -> std::shared_ptr<bool> // Through a constructor
然而,
f1(1);
不行,因为没有可用于将 1
转换为 shared_ptr<bool>
的转换。
std::shared_ptr<T>
有一个采用 std::nullptr_t
的构造函数,其中存在从任何有效的空指针常量(包括普通 0
文字)的隐式转换。另一方面,1
不是任何 shared_ptr
构造函数的有效参数。
除了其他答案之外,一种解决方法是改用 std::make_shared 宏:
f1(std::make_shared<bool>(0)); // OK
f1(std::make_shared<bool>(1)); // OK
这样您就可以向函数提供任何整数文字。简单的工作示例:
#include <iostream>
#include <memory>
void f1(std::shared_ptr<bool> ptr) {
std::cout << std::boolalpha << *ptr << '\n';
}
int main() {
f1(std::make_shared<bool>(0)); // OK
f1(std::make_shared<bool>(1)); // OK
f1(std::make_shared<bool>(2)); // OK
}