代码之家  ›  专栏  ›  技术社区  ›  PiotrK

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

  •  3
  • PiotrK  · 技术社区  · 7 年前

    当相关对象可能不存在时,创建用于从索引自定义容器检索对象的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。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Davis Herring    7 年前

    可分辨的 要素

    完成 bool contains(int index) const;

    1. 一些专家 believe that logic_error is always a mistake
    2. T 必须是可构造的值(类似但不相同于 -可施工)。
    3. [[nodiscard]] )。
    4. 每次调用都必须构造对象。可以将默认值作为一个引用,以允许引用返回(并支持检测缺少值的繁琐形式),但为了避免允许临时参数,则需要使用右值引用重载(或受约束的模板)。
    5. map::operator[]

    {} ,仅1 map::at optional suggestion 效率高,而且很方便。也许最快的变化是返回 const T* T if(std::cin >> x)

        2
  •  1
  •   seccpur    7 年前

    boost::optional<T> get(int index, T& obj)
    {
        if(not_exists(index))
            boost::none;
        else
            return get_base(index);
    }