簡體   English   中英

用於可空引用的C ++慣用方法

[英]C++ idiomatic way for nullable reference

我正在編寫一個函數,它應該接受const std::string & ,但也是一個特殊的nullptr值。 目前,我正在使用const std::string * 但是,我覺得應該有更多的C ++ - ish方式來執行此任務。

我最強的對應點是傳遞值(字符串不會很長,但64kB不是我想復制的東西)。 這也意味着我不希望像optional<T>這樣的對象具有類型為T的值字段。 另外,我不想使用任何外部庫。 我的項目沒有使用Boost或GSL,只是簡單的C ++(確切地說是C ++ 17)。

是否存在標准庫類(奇跡出現在namespace std )或廣泛接受的習慣用語?

如果std::optional支持引用,那么它就是花哨的“現代”方式。

但:

  • 它沒有,而且
  • 有時是花哨的,而“現代的”並不是它的全部。

歷史悠久,久經考驗且清晰易讀的解決方案是采用指針。 這種方法完全可以滿足您的所有需求。

只要這樣做,然后繼續把你寶貴的時間花在更重要的事情上!

這個問題的一個有趣的方面是我更常見的反向透視:C ++方式指定一個不允許為空的指針是什么? 答案歸結為相同的原則。

指針引用的主要區別是:

  1. 可以使指針指向不同的對象。
  2. 指針可以為null。

如果你使指針不變,第一個區別就會消失。 擁有“可空引用”的C ++方法是擁有一個常量指針。 請注意,我所說的指針是常量,如T * const ,它與指向對象的常量無關,如T const *const T *

你可能已經接受過訓練,認為所有的指針都是邪惡的,但這是一種過度概括。 原始指針是引用負責的內存的可選對象好方法。 如果您負責釋放內存,請使用智能指針,但如果其他人正在為您保留內存,請使用引用或指針。 如果需要對象,則使用引用(不能為null); 如果它是可選的指針(可以為null)。 哦,這假設您不需要更改指向的對象,在這種情況下,引用將不再是一個選項。

話雖如此,在特定情況下可能有其他選擇。 如果null和not-null之間沒有共享代碼,那么重載函數可能會更好,比如void foo(const std::string &)void foo() 這必須與各種權衡取得平衡,包括API一致性。 選擇最適合您情況的方法。

另一種方法是提供一個空字符串,您的函數可以通過對象標識檢查來檢測:

#include <string>

namespace MyLibrary
{
   static const std::string NULL_STRING;

   void foo(const std::string& str)
   {
      if (&str == &NULL_STRING)
         // ...
      else
         // ...
   }
}

int main()
{
   MyLibrary::foo("Hello, world!");
   MyLibrary::foo("");

   MyLibrary::foo(MyLibrary::NULL_STRING);
}

不過,人們可能會認為這有點浪費空間,我並不認為這是特別慣用的。 但是,我有時在私有庫代碼中采用了類似的方法(特別是與默認參數相結合)。

正如你特別要求一些STD庫奇跡一樣:STD庫實際上有一個reference_wrapper ,它可以與optional結合使用,以達到你的要求:

template <class T>
using optional_ref = std::optional<std::reference_wrapper<T>>;

它實際上非常直接,但也有點笨拙的訪問:

void foo(optional_ref<std::string> str)
{
    if (str)
        printf("%s", str->get().c_str());
}

從調用站點它工作得很好:

std::string str;
foo(str); // passes a reference
foo({}); // passes nothing

話雖如此,我也不認為使用;)(見接受的答案)。

寫兩個功能:

void f(const string *s)
{
    if (s)
    {
        // Use s
    }
    else
    {
        // Don't use s
    }
}

void f(const string &s)
{
    f(&s);
}

暫無
暫無

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

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