我正在修改here代码:

#include <boost/describe.hpp>
#include <boost/mp11.hpp>
#include <boost/json.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/string_view.hpp>
#include <stdexcept>
#include <string>
#include<iostream>
template<class C1, class C2, class R, class... A, std::size_t... I>
boost::json::value
call_impl_(C1& c1, R(C2::* pmf)(A...), boost::json::array const& args,
  std::index_sequence<I...>)
{
  return boost::json::value_from(
    (c1.*pmf)(
      boost::json::value_to< boost::remove_cv_ref_t<A> >(args[I])...));
}

template<class C1, class C2, class R, class... A>
boost::json::value
call_impl(C1& c1, R(C2::* pmf)(A...), boost::json::array const& args)
{
  if (args.size() != sizeof...(A))
  {
    throw std::invalid_argument("Invalid number of arguments");
  }

  return call_impl_(c1, pmf, args, std::index_sequence_for<A...>());
}

template<class C>
boost::json::value
call(C& c, boost::string_view method, boost::json::value const& args)
{
  using Fd = boost::describe::describe_members<C,
    boost::describe::mod_public | boost::describe::mod_function>;

  bool found = false;
  boost::json::value result;

  boost::mp11::mp_for_each<Fd>([&](auto D) {

    if (!found && method == D.name)
    {
      result = call_impl(c, D.pointer, args.as_array());
      found = true;
    }

    });

  if (!found)
  {
    throw std::invalid_argument("Invalid method name");
  }

  return result;
}

struct Object
{
  std::string greet(std::string const& who)
  {
    return "Hello, " + who + "!";
  }

  int add(int x, int y)
  {
    return x + y;
  }
  int foobar()
  {
    std::cout << "I'm stupid!" << std::endl;
    return 1;
  }
};

BOOST_DESCRIBE_STRUCT(Object, (), (greet, add, foobar))

int main()
{
  Object obj;
  std::cout << call(obj, "greet", { "world" }) << std::endl;
  std::cout << call(obj, "add", { 1, 2 }) << std::endl;
  boost::json::value sc{};
  std::cout << call(obj, "add", sc) << std::endl;
}

我添加的部分是

int foobar()
{
    std::cout << "I'm stupid!" << std::endl;
    return 1;
}

boost::json::value sc{};
std::cout << call(obj, "foobar", sc) << std::endl;

输出:

error C2672: 'call_impl': no matching overloaded function found

I know I can add an overload of call_impl 和 modify call to:

  boost::mp11::mp_for_each<Fd>([&](auto D) {
    if (!found && method == D.name)
    {
      auto temp = args.as_array();
      std::cout << typeid(temp).name() << std::endl;
      if (!temp.empty())
      result = call_impl(c, D.pointer,temp );
      else
        result = call_impl(c, D.pointer);
      found = true;
    }});

我的问题是:

  1. 如何构造包含空值的boost::json::value,以便我可以使用它调用该函数.

I think I've described my problem clearly, so many of my attempts 和 manipulations are so wrong that they don't need to be written, but it still warns me "It looks like your post is mostly code; please add some more details." ...

OS:windows11
IDE:visual studio2019

推荐答案

参数需要作为JSON数组传递.满足要求的最简单方法是:

std::cout << call(obj, "foobar", boost::json::array{}) << std::endl;

参见100

#include <boost/describe.hpp>
#include <boost/json.hpp>
#include <boost/json/src.hpp> // for Coliru
#include <boost/mp11.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/string_view.hpp>
#include <iostream>
#include <stdexcept>
#include <string>

template <class C1, class C2, class R, class... A, std::size_t... I>
boost::json::value call_impl_(C1& c1, R (C2::*pmf)(A...),
                              boost::json::array const& args,
                              std::index_sequence<I...>) {
    return boost::json::value_from((c1.*pmf)(
        boost::json::value_to<boost::remove_cv_ref_t<A>>(args[I])...));
}

template <class C1, class C2, class R, class... A>
boost::json::value call_impl(C1& c1, R (C2::*pmf)(A...),
                             boost::json::array const& args) {
    if (args.size() != sizeof...(A)) {
        throw std::invalid_argument("Invalid number of arguments");
    }

    return call_impl_(c1, pmf, args, std::index_sequence_for<A...>());
}

template <class C>
boost::json::value call(C& c, boost::string_view method,
                        boost::json::value const& args) {
    using Fd =
        boost::describe::describe_members<C,
                                          boost::describe::mod_public |
                                              boost::describe::mod_function>;

    bool found = false;
    boost::json::value result;

    boost::mp11::mp_for_each<Fd>([&](auto D) {
        if (!found && method == D.name) {
            result = call_impl(c, D.pointer, args.as_array());
            found = true;
        }
    });

    if (!found) {
        throw std::invalid_argument("Invalid method name");
    }

    return result;
}

struct Object {
    std::string greet(std::string const& who) {
        return "Hello, " + who + "!";
    }

    int foobar() {
        std::cout << "I'm not so stupid after all!" << std::endl;
        return 42;
    }

    int add(int x, int y) {
        return x + y;
    }
};

BOOST_DESCRIBE_STRUCT(Object, (), (greet, add, foobar))

#include <iostream>

int main() {
    Object obj;
    std::cout << call(obj, "greet", {"world"}) << std::endl;
    std::cout << call(obj, "add", {1, 2}) << std::endl;
    std::cout << call(obj, "foobar", boost::json::array{}) << std::endl;
}

输出

"Hello, world!"
3
I'm not so stupid after all!
42

当然,您可以将其设为默认参数值100,但实际上,您只会在通用代码中使用它,因为您事先不知道函数没有参数.所以我认为这不会增加任何价值.

Json相关问答推荐

Jolt转换,如果任何字段为空,则将对象值设置为空

从json数组中删除特定元素

为什么JQ筛选器不将原始输入打印为$var|.';文档?

盒子图显示不正确

将PostgreSQL转换为JSON对象

如何将文件夹组织的.json文件合并为一个JSON文件,文件夹/文件名作为键

将pyspark.sql.Rowtype数据转换为Json字符串,消除Azure Databricks NB中的值

(Kotlin)com.google.gson.internal.LinkedTreeMap无法转换为com.example.phonetest2.model.HallData

将 std::可选值存储到 json 文件 C++

GitHub Pages无法正确显示我的项目

如何强制仅有一个元素的数组在JSON中生成方括号

使用不同行数的数据创建嵌套Jolt

如何在 terraform 输出中打印一组用户信息

使用 jq 将消息转换为数组

如何在 Dart 中与多个 map (字典)相交

JQuery,使用 GET 方法发送 JSON 对象

Jackson 中的 readValue 和 readTree:何时使用哪个?

如何向从文件中检索的 JSON 数据添加键值?

Gson 将一组数据对象转换为 json - Android

在播放框架 JsObject 中解析 Json 数组