簡體   English   中英

當函數沒有返回值時,返回類型應該是什么?

[英]What should the return type be when the function might not have a value to return?

在過去,你可能有這樣的功能:

const char* find_response(const char* const id) const;

如果找不到該項,則可以返回null以指示該事實,否則顯然返回相關的字符串。

但是當函數改為:

const std::string& find_response(const std::string& id) const;

您返回什么表示未找到項目?

或者簽名真的應該是:

bool find_response(const std::string& id, std::string& value) const;

什么是最優雅的現代C ++方式?

boost::optional 它專門針對這種情況而設計。

注意,它將作為 std::optional包含在即將推出的C ++ 14標准中。 更新:在審查了N3690的國家機構評論后, std::optional從C ++ 14工作文件中退出了單獨的技術規范。 它不是n3797中C ++ 14草案的一部分。

std::unique_ptr相比,它避免了動態內存分配,並更清楚地表達了它的用途。 std::unique_ptr更適用於多態(例如工廠方法)和將值存儲在容器中。

用法示例:

#include <string>
#include <boost/none.hpp>
#include <boost/optional.hpp>

class A
{
private:
    std::string value;
public:
    A(std::string s) : value(s) {}

    boost::optional<std::string> find_response(const std::string& id) const
    {
        if(id == value)
            return std::string("Found it!");
        else
            return boost::none;
        //or
        //return boost::make_optional(id == value, std::string("Found it!"));
    }

    //You can use boost::optional with references,
    //but I'm unfamiliar with possible applications of this.
    boost::optional<const std::string&> get_id() const
    {
        return value;
    }
};

#include <iostream>

int main()
{
    A a("42");
    boost::optional<std::string> response = a.find_response("42"); //auto is handy
    if(response)
    {
        std::cout << *response;
    }
}

什么是最優雅的現代C ++方式?

一如既往,不僅僅是這個問題的一個解決方案。

如果您決定采用任何引用原始共振實例的解決方案,那么在別名和內存管理方面,尤其是在多線程環境中,您處於一個很滑的道路上。 通過將響應復制到調用者,不會出現這樣的問題。

今天,我會這樣做:

std::unique_ptr<std::string> find_response(const std::string& id) const;

這樣,您可以檢查nullptr為“在過去的日子里” 並且100%清楚誰清除返回的實例是誰的責任:調用者。

我看到的唯一不足之處是響應字符串的附加副本,但是在測量和證明之前不要忽略它作為缺點。

另一種方法是在搜索std::set<>std::map<> - 返回std::pair<bool, const char*>其中一個值是bool is_found而另一個是const char* response 這樣你就不會得到附加響應副本的“開銷”,只有返回的std::pair<>可能會被編譯器最大限度地優化。

如果函數通過引用返回一個字符串,但需要能夠指示不存在這樣的字符串,那么最明顯的解決方案是返回一個指針,該指針基本上是一個可以為null的引用,即確切地追求的內容。

const std::string* find_response(const std::string& id) const;

這里有幾個很好的解決方案。 但為了完整起見,我想補充一點。 如果您不想依賴boost::optional您可以輕松實現自己的類

class SearchResult
{
    SearchResult(std::string stringFound, bool isValid = true)
        : m_stringFound(stringFound),
        m_isResultValid(isValid)
    { }

    const std::string &getString() const { return m_stringFound; }
    bool isValid() const { return m_isResultValid; }

private:
    std::string m_stringFound;
    bool m_isResultValid;
};

顯然你的方法簽名就像這樣

const SearchResult& find_response(const std::string& id) const;

但基本上與增強解決方案相同。

如果需要返回一個可空的實體,則可以原諒在C ++中使用指針。 這被廣泛接受。 但當然bool find_response(const std::string& id, std::string& value) const; 很冗長。 所以這是你的選擇問題。

我認為第二種方式更好。 或者你可以像這樣寫:

int find_response(const std::string& id, std::string& value) const;

如果此函數返回-1,則表示您沒有找到響應。

暫無
暫無

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

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