InputValidator для json - G CC ошибка компиляции - PullRequest
0 голосов
/ 26 января 2020

Я использую nlohmann json библиотеку , которая имеет функцию json::get<>(), чтобы получить значение из json с проверкой типа. Выдает исключение при несовпадении типов. В моем проекте мне нужна проверка ввода json (если все объекты присутствуют, включая правильные типы), поэтому я построил что-то вроде этого:

#include <string>
#include <tuple>
#include <iostream>
#include "nlohmann/json.hpp"

using namespace nlohmann;

template<typename _Tp>
class ValidatorField
{
public:
    using type = _Tp;

    ValidatorField(const std::string& tp) : fieldName(tp) {}
    const std::string& getName() const { return fieldName; }

private:
    std::string fieldName;
};

using string_t = ValidatorField<std::string>;
using int_t = ValidatorField<int>;
using bool_t = ValidatorField<bool>;

template<std::size_t N, class... _Ts>
static inline std::enable_if_t<N==0, bool> typeCheck(const json& j, const std::tuple<_Ts...>& tuple) noexcept
{
    try
    {
        if (j.find(std::get<N>(tuple).getName()) != j.end())
        {
            j[std::get<N>(tuple).getName()].get<std::tuple_element_t<N, std::tuple<_Ts...>>::type>();
            return true;
        }
        return false;
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
        return false;
    }
}

template<std::size_t N, class... _Ts>
static inline std::enable_if_t < 0 < N, bool > typeCheck(const json& j, const std::tuple<_Ts...>& tuple) noexcept
{
    try
    {
        if (j.find(std::get<N>(tuple).getName()) != j.end())
        {
            j[std::get<N>(tuple).getName()].get<std::tuple_element_t<N, std::tuple<_Ts...>>::type>();
            return typeCheck<N-1>(j, tuple);
        }
        return false;
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
        return false;
    }
}

class object_t
{
public:
    template<typename... _Ts>
    object_t(const std::string& tp, const std::tuple<_Ts...>& fields, const json& j) : fieldName(tp)
    {
        std::cout << std::boolalpha << typeCheck<std::tuple_size_v<std::tuple<_Ts...>> - 1, _Ts...>(j, fields) << std::endl;
    }

private:
    std::string fieldName;
};

int main()
{
    json j = json::object();
    j["field1"] = "strValue";
    j["field2"] = 4;
    j["field3"] = 4;
    std::cout << j.dump(4) << std::endl;

    object_t("branch", std::make_tuple(
        string_t {"field1"},
        int_t {"field2"},
        int_t {"field3"}
    ), j);
}

, который работает на удивление хорошо - за исключением только clang.
Пример вывода:

{
    "field1": "strValue",
    "field2": 4,
    "field3": 4
}
true

Я пытался скомпилировать его с помощью G CC - что дало следующий результат: enter image description here Есть идеи, почему я вижу такое поведение?

РЕДАКТИРОВАТЬ 1 :
Если я удаляю содержимое в скобках [], оно работает просто отлично. Также, если я заменю [std::get<N>(tuple).getName()] на ["const-string"], он тоже будет работать.
Я бы склонялся к вероятности, что это ошибка в G CC

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...