简体   繁体   English

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

Both as int , why 0 but 1 can be converted to std::shared_ptr<T> ?两者都是int ,为什么01可以转换为std::shared_ptr<T>

How the disability of conversion from 1 to std::shared_ptr<T> be checked when compiling?编译时如何检查从1转换为std::shared_ptr<T>的失效?

How the disability of conversion from 1 to std::nullptr_t be checked when compiling?编译时如何检查从1转换为std::nullptr_t的失效?

0 is a special value in C/C++. 0是 C/C++ 中的一个特殊值。 Many things work with 0 but not with 1 .许多事情适用于0但不适用于1 The reason(s) for that are the conversion rules of the language.原因是语言的转换规则。

f1(0); // OK

That's ok because of the following conversions.没关系,因为有以下转换。

0  -> nullptr
nullptr -> std::shared_ptr<bool> // Through a constructor

However,然而,

f1(1);

is not ok since there is no conversion available to convert 1 to a shared_ptr<bool> .不行,因为没有可用于将1转换为shared_ptr<bool>的转换。

std::shared_ptr<T> has a constructor taking a std::nullptr_t , for which there exist an implicit conversion from any valid null pointer constant, which includes a plain 0 literal. std::shared_ptr<T>有一个采用std::nullptr_t的构造函数,对于该构造函数,存在从任何有效的空指针常量进行的隐式转换,其中包括一个普通的0文字。 On the other hand, 1 is not a valid argument for any shared_ptr constructor.另一方面, 1不是任何shared_ptr构造函数的有效参数。

In addition to other answers, one workaround would be to use thestd::make_shared macro instead:除了其他答案之外,一种解决方法是改用std::make_shared宏:

f1(std::make_shared<bool>(0)); // OK
f1(std::make_shared<bool>(1)); // OK

This way you will be able to supply any integer literal to the function.这样,您将能够为函数提供任何整数文字。 Simple working example:简单的工作示例:

#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
}

Some notes:一些注意事项:

  • Integral literals of zero value, such as 0 , 0LL , 0x0 etc, are null pointer constants .零值的整数文字,例如00LL0x0等,是空指针常量

  • nullptr is also a null pointer constant . nullptr也是一个空指针常量

  • Non-literals, such as +0 , -0 , int{0} , (void*)0 , etc, are NOT null pointer constants .非文字,例如+0-0int{0}(void*)0等,不是空指针常量

  • Null pointer constants are implicit convertible to any pointer type and nullptr_t .空指针常量可以隐式转换为任何指针类型和nullptr_t

Integral null pointer constants have been introducing problems since they are defined.自定义以来,积分空指针常量就一直在引入问题。

For example,例如,

void foo(const string&);
foo(0);

compiles and calls the constructor string(const char*) with a null pointer value, which is undefined behavior.编译并使用空指针值调用构造函数string(const char*) ,这是未定义的行为。 (C++23 adds an overload string(nullptr_t) = delete , which also disables constructing from 0 due to ambiguous matches.) (C++23 添加了一个重载string(nullptr_t) = delete ,由于不明确的匹配,它也禁止从0构造。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM