简体   繁体   English

当函数没有返回值时,返回类型应该是什么?

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

In the old days, you might have a function like this: 在过去,你可能有这样的功能:

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

If the item could not be found, then a null could be returned to indicate the fact, otherwise obviously return the relevant string. 如果找不到该项,则可以返回null以指示该事实,否则显然返回相关的字符串。

But when the function is changed to: 但是当函数改为:

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

What do you return to indicate item not found? 您返回什么表示未找到项目?

Or should signature really be: 或者签名真的应该是:

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

What would be the most elegant modern C++ way? 什么是最优雅的现代C ++方式?

boost::optional . boost::optional It was specifically designed for this kind of situation. 它专门针对这种情况而设计。

Note, it will be included in upcoming C++14 standard as std::optional . 注意,它将作为 std::optional包含在即将推出的C ++ 14标准中。 Update: After reviewing national body comments to N3690, std::optional was voted out from C++14 working paper into a separate Technical Specification. 更新:在审查了N3690的国家机构评论后, std::optional从C ++ 14工作文件中退出了单独的技术规范。 It is not a part of the draft C++14 as of n3797. 它不是n3797中C ++ 14草案的一部分。

Compared to std::unique_ptr , it avoids dynamic memory allocation, and expresses more clearly its purpose. std::unique_ptr相比,它避免了动态内存分配,并更清楚地表达了它的用途。 std::unique_ptr is better for polymorphism (eg factory methods) and storing values in containers, however. std::unique_ptr更适用于多态(例如工厂方法)和将值存储在容器中。

Usage example: 用法示例:

#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;
    }
}

What would be the most elegant modern C++ way? 什么是最优雅的现代C ++方式?

There's, as always, not just one solution to this problem. 一如既往,不仅仅是这个问题的一个解决方案。

If you decide to go for any solution that references the original resonse instance, you're on a slippery road when it comes to aliasing and memory management, especially in a multi threaded environment. 如果您决定采用任何引用原始共振实例的解决方案,那么在别名和内存管理方面,尤其是在多线程环境中,您处于一个很滑的道路上。 By copying the response to the caller, no such issues arises. 通过将响应复制到调用者,不会出现这样的问题。

Today, I would do this: 今天,我会这样做:

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

That way, you can check for nullptr as "in the olden days" and it's 100% clear who's responsibility it is to clear up the returned instance: the caller. 这样,您可以检查nullptr为“在过去的日子里” 并且100%清楚谁清除返回的实例是谁的责任:调用者。

The only downside I see of this, is the additional copy of the response string, but don't dismiss that as a downside until measured and proven so. 我看到的唯一不足之处是响应字符串的附加副本,但是在测量和证明之前不要忽略它作为缺点。

Another way is to do as is done when searching std::set<> and std::map<> - return a std::pair<bool, const char*> where one value is bool is_found and the other is const char* response . 另一种方法是在搜索std::set<>std::map<> - 返回std::pair<bool, const char*>其中一个值是bool is_found而另一个是const char* response That way you don't get the "overhead" of the additional response copy, only of the returned std::pair<> which is likely to be maximally optimized by the compiler. 这样你就不会得到附加响应副本的“开销”,只有返回的std::pair<>可能会被编译器最大限度地优化。

如果函数通过引用返回一个字符串,但需要能够指示不存在这样的字符串,那么最明显的解决方案是返回一个指针,该指针基本上是一个可以为null的引用,即确切地追求的内容。

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

There are several good solutions here already. 这里有几个很好的解决方案。 But for the sake of completeness I'd like to add this one. 但为了完整起见,我想补充一点。 If you don't want to rely on boost::optional you may easily implement your own class like 如果您不想依赖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;
};

Obviously your method signature looks like this then 显然你的方法签名就像这样

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

But basically that's the same as the boost solution. 但基本上与增强解决方案相同。

Use of pointers in C++ is forgiven if you need to return a nullable entity. 如果需要返回一个可空的实体,则可以原谅在C ++中使用指针。 This is widely accepted. 这被广泛接受。 But of course bool find_response(const std::string& id, std::string& value) const; 但当然bool find_response(const std::string& id, std::string& value) const; is quite verbose. 很冗长。 So it is a matter of your choice. 所以这是你的选择问题。

I think the second way is better. 我认为第二种方式更好。 Or you can write like this: 或者你可以像这样写:

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

if this function return -1, it tells that you don't find the response. 如果此函数返回-1,则表示您没有找到响应。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果未分配返回未定义对象类型引用的C ++函数的返回值,会发生什么? - What should happen when the return value from a C++ function that returns a reference of an undefined object type is not assigned? 这个函数应该返回什么类型的对象? - What type of object should this function return? 对于具有引用返回类型的搜索算法,默认返回值应该是什么? - For a search algo with reference return type, what should be the default return value? 函数在应该返回值时不返回值 - Function does not return value when it should 我应该使用什么函数签名来返回对可能不存在的对象的引用? - What function signature should I use to return a reference to an object that might not exist? 这个函数的返回类型是什么? - What is the return type of this function? 当返回类型是一个类时,指向返回值的指针的名称是什么? - When the return type is a class, what's the name of the pointer to the return value? 下面的多参数 function 模板的返回类型应该是什么? - What should be the return type of the following function template with multiple parameters? 返回向量大小的getter应该返回什么类型的值? - What type of value should it be returned by getters that return size of vector? 如果我没有返回未知类型的东西,我应该返回什么 - what should I return if I don't have something to return for an unknown type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM