C++ 使用可选来表示功能失败

示例

在C ++ 17之前,函数通常以几种方式之一表示故障:

  • 返回了空指针。

    • 例如,在没有委托的实例上调用函数将返回。Delegate *App::get_delegate()Appnullptr

    • 对于已动态分配或很大且由指针管理的对象,这是一个很好的解决方案,但对于通常是堆栈分配并通过复制传递的小对象来说,这不是一个好的解决方案。

  • 返回类型的特定值被保留以指示失败。

    • 例如,在两个未连接的顶点上调用函数可能会返回零以表明这一事实。unsigned shortest_path_distance(Vertex a, Vertex b)

  • 该值与一起配对bool,表示返回的值有意义。

    • 例如std::pair<int, bool> parse(const std::string &str),使用不是整数的字符串参数调用函数将返回一对未定义int且bool设置为的对false。

在此示例中,给了约翰两只宠物,绒毛和毛绒宠物。然后调用该函数以检索John的宠物晶须。由于John没有名为Whiskers的宠物,因此该函数失败并返回。Person::pet_with_name()std::nullopt

#include <iostream>
#include <optional>
#include <string>
#include <vector>

struct Animal {
    std::string name;
};

struct Person {
    std::string name;
    std::vector<Animal> pets;
    
    std::optional<Animal> pet_with_name(const std::string &name) {
        for (const Animal &pet : pets) {
            if (pet.name == name) {
                return pet;
            }
        }
        return std::nullopt;
    }
};

int main() {
    Person john;
   john.name= "John";
    
    Animal fluffy;
   fluffy.name= "Fluffy";
    john.pets.push_back(fluffy);
    
    Animal furball;
   furball.name= "Furball";
    john.pets.push_back(furball);
    
    std::optional<Animal> whiskers = john.pet_with_name("Whiskers");
    if (whiskers) {
        std::cout << "约翰有一只叫胡须的宠物。" << std::endl;
    }
    else {
        std::cout << "胡须不能属于约翰。" << std::endl;
    }
}