跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组
折叠
品牌标识

D2Learn Forums

dustchensD

dustchens

@dustchens
关于
帖子
3
主题
1
群组
0
粉丝
0
关注
0

帖子

最新 最佳 有争议的

  • json库的initializer_list创建问题
    dustchensD dustchens

    @SPeak
    按照这个思路,只保留一个列表初始化,用了一个辅助函数检测了每个元素是否是数组,如果是数组就检测长度是否是2,然后首元素是否是string,如果初始化列表里全部元素都符合就判定为object。这个代码运行成功了,感谢大佬

      Json(std::initializer_list<Json> init) {
        if (is_object_list(init)) {
          JsonObject dict;
          for (const auto &el : init) {
            auto pair = std::get_if<JsonArray>(&el.m_value);
            // 必须是长度为2的数组
            assert(pair && pair->size() == 2);
            auto key = std::get_if<std::string>(&(*pair)[0].m_value);
            // 第一个元素必须是字符串
            assert(key);
            dict.emplace(*key, (*pair)[1]);
          }
          m_value = std::move(dict);
        } else {
          m_value = JsonArray(init);
        }
      }
    
      bool is_object_list(std::initializer_list<Json> init) {
        return std::all_of(init.begin(), init.end(), [](const Json &el) {
          auto pair = std::get_if<JsonArray>(&el.m_value);
          if (!pair || pair->size() != 2)
            return false;
          return std::holds_alternative<std::string>((*pair)[0].m_value);
        });
      }
    

  • json库的initializer_list创建问题
    dustchensD dustchens

    可能给每个类型都加一个构造函数也是有问题的设计,也许需要一个模板替代


  • json库的initializer_list创建问题
    dustchensD dustchens

    用c++17 variant实现的json库,想实现用 {} 大括号快速构建一个嵌套的json对象,但是加入了initializerlist后出现了灾难性的构造问题,无法构造数组、对象类型,更无法构建复杂的嵌套类型。如果去掉其中一个列表初始化,只保留构建数组的初始化列表,也不能实现匹配的问题,除非在构造时手动标明类型,但这和列表初始化的初衷完全背离了

    main

    #include "include/json/json.h"
    #include <iostream>
    
    using myjson::Json;
    using std::cin, std::cout, std::endl;
    int main(int, char **) {
      // 数组也无法用initializer_list构造,除非将部分单参数构造变为隐式,但这本质就是错误的,可能导致一系列问题
      Json json_1 { 3.141, 2, 17};
      // Json json2
      // {
      //     {"pi", 3.141},
      //     {"happy", true},
      //     {"name", "Niels"},
      //     {"nothing", nullptr},
      //     {
      //         "answer", {
      //             {"everything", 42}
      //         }
      //     },
      //     {"list", {1, 0, 2}}
      // };
      cout<<json_1.is_array()<<endl;
      cout<<json_2.is_object()<<endl;
      return 0;
    }
    
    

    json.h

    #pragma once
    
    #include <cstddef>
    #include <initializer_list>
    #include <stdexcept>
    #include <string>
    #include <unordered_map>
    #include <utility>
    #include <variant>
    #include <vector>
    
    namespace myjson {
    class Json;
    
    template <typename... Ts> struct overload : Ts... {
      using Ts::operator()...;
    };
    template <typename... Ts> overload(Ts...) -> overload<Ts...>;
    
    using JsonArray = std::vector<Json>;
    using JsonObject = std::unordered_map<std::string, Json>;
    
    class Json {
    public:
      using ValueType = std::variant<std::nullptr_t, bool, int, double, std::string,
                                     JsonArray, JsonObject>;
    public:
      Json() : m_value(nullptr) {}
      Json(const Json &) = default;
      Json(Json &&) = default;
      ~Json() = default;
      // 从基本类型构造
      Json(std::nullptr_t) : m_value(nullptr) {}
      explicit Json(bool value) : m_value(value) {}
      // 防止 bool 构造为 int
      template<typename Int, typename = std::enable_if_t<std::is_integral_v<Int>
      && !std::is_same_v<Int, bool>>> 
      explicit Json(int value) noexcept : m_value(static_cast<int>(value)) {} 
      explicit Json(double value) : m_value(value) {}
      explicit Json(const std::string& value) : m_value(value) {}
    
      //const char* 是否需要构造存疑
      // explicit Json(const char* value) : m_value(std::string(value)) {}
      explicit Json(JsonArray value) : m_value(std::move(value)) {}
      explicit Json(JsonObject value) : m_value(std::move(value)) {}
    
      
        Json(std::initializer_list<Json> init){
          JsonArray array;
          for (const auto& element : init) {
              array.emplace_back(element);
          }
          m_value = std::move(array);
      }
      // object initializer_list构造
      // Json(std::initializer_list<std::pair<const std::string, Json>> init) {
      //     JsonObject dict;
      //     for (const auto& p : init) {
      //         dict.insert(p);
      //     }
      //     m_value = std::move(dict);
      // }
    
      Json &operator=(const Json &other) = default;
      Json &operator=(Json &&other) = default;
    
    public:
      [[nodiscard]] constexpr bool is_boolean() const noexcept {
        return std::holds_alternative<bool>(m_value);
      }
      [[nodiscard]] constexpr bool is_integer() const noexcept {
        return std::holds_alternative<int>(m_value);
      }
      [[nodiscard]] constexpr bool is_null() const noexcept {
        return std::holds_alternative<nullptr_t>(m_value);
      }
      [[nodiscard]] constexpr bool is_double() const noexcept {
        return std::holds_alternative<double>(m_value);
      }
      [[nodiscard]] constexpr bool is_string() const noexcept {
        return std::holds_alternative<std::string>(m_value);
      }
      [[nodiscard]] constexpr bool is_array() const noexcept {
        return std::holds_alternative<JsonArray>(m_value);
      }
      [[nodiscard]] constexpr bool is_object() const noexcept {
        return std::holds_alternative<JsonObject>(m_value);
      }
    
      template <typename T> const T &get() const {
        if (!std::holds_alternative<T>(m_value))
          throw std::runtime_error("type mismatch");
        return std::get<T>(m_value);
      }
    
      template <typename T> T &get() {
        if (!std::holds_alternative<T>(m_value))
          throw std::runtime_error("type mismatch");
        return std::get<T>(m_value);
      }
    JsonArray as_array() {
      if (!is_array())
        throw std::runtime_error("Not an array");
      return get<JsonArray>();
    }
    
    JsonObject as_dict() {
      if (!is_object())
        throw std::runtime_error("Not an dict");
      return get<JsonObject>();
    }
    
    private:
      ValueType m_value;
    };
    
    } // namespace myjson
    
  • 登录

  • 没有帐号? 注册

  • 登录或注册以进行搜索。
d2learn forums Powered by NodeBB
  • 第一个帖子
    最后一个帖子
0
  • 版块
  • 最新
  • 标签
  • 热门
  • Online Tools
  • 用户
  • 群组