[英]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
,为什么0
但1
可以转换为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 .零值的整数文字,例如
0
、 0LL
、 0x0
等,是空指针常量。
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
、 -0
、 int{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.