为什么我可以将 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>

如何检查编译时1std::shared_ptr<T>的转换是否失效?

编译时如何检查1std::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
}