如何使用 boost::json::value 调用无参数函数
How to call a parameterless function using boost::json::value
我正在修改 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
我知道我可以添加 call_impl 的重载并将调用修改为:
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;
}});
我的问题是:
- 如何构造一个包含空值的boost::json::value,这样我就可以用它来调用那个函数
我想我已经把我的问题描述清楚了,所以我的很多尝试和操作都是错误的,不需要写,但它仍然警告我“看起来像你的post主要是代码;请添加更多详细信息。” ...
OS:windows11
IDE:visual studio2019
参数需要作为 JSON 数组传递。满足要求的最简单方法是:
std::cout << call(obj, "foobar", boost::json::array{}) << std::endl;
#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
当然你可以将其设置为默认参数值:Live Demo 但实际上,你只会在通用代码中使用它,而你并不知道事先说明函数没有参数。所以我认为这不会增加任何价值。
我正在修改 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
我知道我可以添加 call_impl 的重载并将调用修改为:
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;
}});
我的问题是:
- 如何构造一个包含空值的boost::json::value,这样我就可以用它来调用那个函数
我想我已经把我的问题描述清楚了,所以我的很多尝试和操作都是错误的,不需要写,但它仍然警告我“看起来像你的post主要是代码;请添加更多详细信息。” ...
OS:windows11
IDE:visual studio2019
参数需要作为 JSON 数组传递。满足要求的最简单方法是:
std::cout << call(obj, "foobar", boost::json::array{}) << std::endl;
#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
当然你可以将其设置为默认参数值:Live Demo 但实际上,你只会在通用代码中使用它,而你并不知道事先说明函数没有参数。所以我认为这不会增加任何价值。