簡體   English   中英

當函數返回類型為bool時,為什么我不能在C ++ 14中返回共享指針?

[英]Why can't I return a shared pointer in C++14 when the function return type is bool?

我正在使用g ++並編寫一個簡單的函數:

#include <memory>

std::shared_ptr<char> ptr;

bool fails_compiling()
{
    return ptr;
}

從我在界面中看到的, shared_ptr實現包括一個bool操作符,我甚至可以應用這樣的快速修復:

    return static_cast<bool>(ptr);

它現在編譯。

為什么返回算法不像if()while()那樣嘗試自動轉換為bool

如果你簽出std::shared_ptr的bool轉換運算符,你會看到它被聲明為:

explicit operator bool() const;

使用explicit只是告訴編譯器禁止隱式轉換 ,這是因為函數的返回類型與返回的對象類型不同而發生的情況。 但是,這不會影響上下文轉換

發生在任何情況下:

  • 控制ifwhilefor表達式;
  • 邏輯運算符! &&|| ;
  • 條件運算符?: ;
  • static_assert ;
  • noexcept

以上引用來自cppreference

為什么返回算法不像if()while()那樣嘗試自動轉換為bool

std :: shared_ptr :: operator boolexplicit轉換函數,因此不允許隱式轉換,但static_cast (顯式轉換)效果很好。

當用於ifwhile上下文轉換生效,則將考慮顯式的用戶定義轉換函數。 在這種情況下, std::shared_ptr可以在上下文中轉換為bool

在以下五個上下文中,預期類型為bool ,如果聲明bool t(e);則構建隱式轉換序列bool t(e); 結構良好。 也就是說,顯式的用戶定義轉換函數,如explicit T::operator bool() const; 被認為。 這種表達e被認為是在語境上可轉換為bool

  • 控制if,while,for的表達式;
  • 邏輯運算符!,&&和||;
  • 條件運算符?:;
  • static_assert;
  • noexcept。

為什么代碼不能編譯。

std::shared_ptr的conversion-to- bool運算符被聲明為explicit ,因此通常不會為隱式轉換調用。

特別是它不會在return語句的上下文中調用。

並且它不會被考慮用於選擇函數重載,即foo(p)將不會解析為帶有bool參數的foo的重載。

然而,有明確表達轉換的方法,包括:

!!ptr

ptr != nullptr

ptr.get() != nullptr

static_cast<bool>( ptr )

ptr.operator bool()

隱式轉換為bool的一般情況。

在某些情況下, operator bool() explicit忽略 ,以便使事情主要像在C ++ 03中那樣工作。 也就是說,在C ++ 11中允許轉換運算符允許使用explicit之前使用的方案。 這些例外是

  • ifwhilefor使用(語法生成) 條件 ,但不在switch

  • 用作以下條件:? choice, static_assertnoexcept

  • 用作內置布爾運算符&&|| 而且! 或它們的等同物andornot

值得注意的是,這些異常允許隱式轉換為bool ,盡管有explicit ,稱為上下文轉換 ,但不包括return語句表達式。


在其他情況下也可以explicit被忽略嗎?

在其他情況下,如果有的話,可以忽略轉換運算符上的explicit嗎?

好吧,沒有。 但是,可以隱式調用非explicit轉換運算符,即隱式轉換運算符,其中上下文未指定要轉換為的確切類型。

某些語言結構需要轉換為具有適合於構造的一組指定類型之一的值。 出現在這樣的上下文中的類類型E的表達式e被稱為在上下文中隱式地轉換為指定類型T並且當且僅當e可以被隱式轉換為如下確定的類型T才是良好形式的: E是搜索返回類型為cv T或對cv T引用的轉換函數,使得上下文允許T 應該只有一個這樣的T

例如,

如果是類類型,則操作數[ delete ]在上下文中被隱式轉換(第4節)到指向對象類型的指針。

......所以,對我來說有點違反直覺!,以下內容應該使用符合標准的編譯器進行編譯:

 struct Foo { operator int*() const { return nullptr; } }; auto main() -> int { delete Foo(); } 

暫無
暫無

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

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