gpt4 book ai didi

c++ - 来自 QVariantList 的 std::function 的通用调用

转载 作者:太空狗 更新时间:2023-10-29 22:55:53 24 4
gpt4 key购买 nike

我正在寻找一种使用 QVariantList 中的参数调用 std::function 的通用方法。此版本有效,但缺点是必须指定模板参数:

template <typename... T>
struct VariantFunc {
static void Invoke(std::function<void(T...)> f, const QVariantList& args)
{
InvokeHelper(f, args);
}

private:
template <typename T1>
static void InvokeHelper(std::function<void(T1)> f, const QVariantList& args)
{
f(args.at(0).value<T1>());
}
template <typename T1, typename T2>
static void InvokeHelper(std::function<void(T1, T2)> f, const QVariantList& args)
{
f(args.at(0).value<T1>(), args.at(1).value<T2>());
}
template <typename T1, typename T2, typename T3>
static void InvokeHelper(std::function<void(T1, T2, T3)> f, const QVariantList& args)
{
f(args.at(0).value<T1>(), args.at(1).value<T2>(), args.at(2).value<T3>());
}
};

auto args = QVariantList() << 100 << QString("hello") << QJsonValue(1234);
auto f = [](int i, QString s, QJsonValue j) { qDebug() << i << s << j; };
VariantFunc<int, QString, QJsonValue>::Invoke(f, args);

我想要这样的实现:

struct VariantFunc2 {
template<typename Func>
static void Invoke(Func f, const QVariantList& args)
{
// ???
}
};

auto args = QVariantList() << 100 << QString("hello") << QJsonValue(1234);
auto f = [](int i, QString s, QJsonValue j) { qDebug() << i << s << j; };
VariantFunc2::Invoke(f, args);

有没有办法在 C++11 中做到这一点?显然,std::function 的推导指南提供了一个解决方案,但 C++11 却没有。

最佳答案

这是一个 C++14 实现。它不使用 std::function,以避免与所述类相关的开销。相反,它使用可调用的完美转发。此外,Invoke 函数返回调用可调用对象的结果。

template <typename F>
struct function_traits;

template <typename R, class... Args>
struct function_traits<R(*)(Args...)> : public function_traits<R(Args...)> {};

template <typename R, class... Args>
struct function_traits<R(Args...)> {};

template <typename C, class R, class... Args>
struct function_traits<R(C::*)(Args...) const> : public function_traits<R(C&, Args...)>
{
using args = std::tuple<Args...>;
};

template <typename F, typename Args, std::size_t ... I>
auto Invoke_impl(F&& f, const QVariantList& args, std::index_sequence<I ...>)
{
return f(args.at(I).value<std::remove_const_t<std::remove_reference_t<std::tuple_element_t<I, Args>>>>() ...);
}

template <typename Func>
auto Invoke(Func&& f, const QVariantList& args)
{
using F = typename std::remove_reference<Func>::type;
using Args = typename function_traits<decltype(&F::operator())>::args;
using Indices = std::make_index_sequence<std::tuple_size<Args>::value>;
return Invoke_impl<Func, Args>(std::forward<Func>(f), args, Indices{});
}

int main()
{
QString msg = "From Lambda";
auto f = [msg](int i, const QString& s, const QJsonValue& j)
{
qDebug() << msg << i << s << j;
return 5;
};
auto args = QVariantList() << 11 << "hello" << QJsonValue(123.456);
qDebug() << Invoke(f, args);
}

关于c++ - 来自 QVariantList 的 std::function 的通用调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50000397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com