簡體   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>’
}

兩者都是int ,為什么01可以轉換為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
}

一些注意事項:

  • 零值的整數文字,例如00LL0x0等,是空指針常量

  • nullptr也是一個空指針常量

  • 非文字,例如+0-0int{0}(void*)0等,不是空指針常量

  • 空指針常量可以隱式轉換為任何指針類型和nullptr_t

自定義以來,積分空指針常量就一直在引入問題。

例如,

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

編譯並使用空指針值調用構造函數string(const char*) ,這是未定義的行為。 (C++23 添加了一個重載string(nullptr_t) = delete ,由於不明確的匹配,它也禁止從0構造。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM