gpt4 book ai didi

c++ - 用于从可能不存在的容器中检索对象的 API 设计

转载 作者:太空狗 更新时间:2023-10-29 21:33:26 25 4
gpt4 key购买 nike

当相关对象可能不存在时,创建用于从索引自定义容器中检索对象的 API 的方法有哪些?

到目前为止我想到了:

  1. 抛出异常

    T get(int index) const
    {
    if(not_exists(index)) throw std::out_of_range("Index is out of range");
    return get_base(index);
    }
  2. 构造T并返回它

    T get(int index) const
    {
    if(not_exists(index)) return T{};
    return get_base(index);
    }
  3. 返回 bool 并检索作为引用

    bool get(int index, T & obj) const
    {
    if(not_exists(index)) return false;
    obj = get_base(index); return true;
    }
  4. 如果找不到则使用默认参数

    T get(int index, T def_obj) const
    {
    if(not_exists(index)) return def_obj;
    return get_base(index);
    }
  5. 合并 4 + 2

    T get(int index, T def_obj = {}) const
    {
    if(not_exists(index)) return def_obj;
    return get_base(index);
    }
  6. 修改容器以添加此类对象(警告 - get 将不再是 const!)

    T get(int index, T def_obj = {})
    {
    if(not_exists(index)) set(index, def_obj);
    return get_base(index);
    }

每种解决方案的优缺点是什么?我错过了什么吗?

我特别担心在高并发环境中进行推理,我希望为客户端提供尽可能直观和安全的 API。

最佳答案

这里的根本问题是语义:#1 和#3 是唯一可以区分存在与不存在的问题; #6 总是成功返回容器的一个元素;而其他人总是成功返回一些。应用程序决定您需要哪些。

在这方面,#1 和#3 是完整的:任何一个都足以实现任何其他(考虑到一些其他添加元素的方法来模拟#6)。如果可以避免来自其他线程的干扰,#4 和#5 同样强大:它们可以通过提供两个不同的默认值来检测缺失。或者,可以添加 bool contains(int index) const; 以允许区分缺失(同样根据需要使用外部同步)。

但是,这些仿真(#1/3 中的#2/4/5 除外)涉及可能性能不足的重复查找。对于某些底层数据结构,可能需要其他操作才能获得最佳性能:例如,将元素从一个索引移动到另一个索引而不重建它。

同时,所有这些方法都存在实际问题,至少在一般情况下是这样。

  1. 一些专家believe that logic_error is always a mistake ;当然,在相当常见的情况下抛出异常是昂贵的。但是,这里可以返回一个引用,这非常有用。
  2. T 必须是值可构造的(与默认可构造的相似但不相同)。
  3. T 必须是可赋值的(并且客户端必须构造一个,可能用于多个调用)。忽略标志可能导致未定义的行为(因此将其标记为 [[nodiscard]])。
  4. 每次调用必须构造两个T 对象。默认值可以是一个引用以允许引用返回(并支持检测缺失值的繁琐形式),但为了避免允许临时参数,则需要右值引用重载(或受约束的模板)。
  5. 与#4 一样,这构造了两个对象。在模板上下文中,对 #2 进行了改进,因为仅当使用默认值时才需要值可构造性。
  6. 这当然可以有三个变体,例如#2/4/5。如果它返回一个引用(如 map::operator[])以允许改变(可能的)新元素,将会更有用。

如果 T 的构建成本可能很高(即使来自 {}),则只有 #1(由 map::at 使用)和 optional suggestion有效率;方便地,它们也很完整。也许最快的变体是返回 const T*,使用空指针表示不存在。在它们之间进行选择是微调性能权衡的问题(除非您的商店通常有异常(exception)或指示)。对于便宜的 T,如果语义足够,#5 是有吸引力的;否则 #3 可能是最好的(因为它与 if(std::cin >> x) 相似)。

关于c++ - 用于从可能不存在的容器中检索对象的 API 设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51056503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com