gpt4 book ai didi

c++ - 引用数据类型的可变参数模板

转载 作者:太空宇宙 更新时间:2023-11-04 12:52:32 25 4
gpt4 key购买 nike

我想为类方法创建一个包装器,所以我使用了一个变量模板和 std::tuple 来包装该方法。它按我的需要工作,但我无法弄清楚如何能够用引用调用的参数包装一个方法。请看下面的主要功能。

#include <iostream>
#include <string>
#include <functional>

using namespace std::placeholders;

namespace helper {

template <std::size_t... Ts> struct index {};

template <std::size_t N, std::size_t... Ts> struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};

template <std::size_t... Ts> struct gen_seq<0, Ts...> : index<Ts...> {};

template<class F, class... Ts, std::size_t... Is> void for_each_in_tuple(std::tuple<Ts...> &tuple, F func, std::index_sequence<Is...>)
{
using expander = int[];
(void)expander {
0, ((void)func(std::get<Is>(tuple)), 0)...
};
}

template<class F, class...Ts> void for_each_in_tuple(std::tuple<Ts...> &tuple, F func)
{
for_each_in_tuple(tuple, func, std::make_index_sequence<sizeof...(Ts)>());
}
}

enum class Result : std::int32_t {
Result1 = 1,
Result2 = 2
};

template<typename... Args> class Procedure {
private:

std::function<Result(Args...)> m_method;
std::tuple<Args...> args;

template <typename... Args, std::size_t... Is> Result callMethod(std::tuple<Args...> &tup, helper::index<Is...>)
{
return m_method(std::get<Is>(tup)...);
}

template <typename... Args> Result callMethod(std::tuple<Args...> &tup)
{
return callMethod(tup, helper::gen_seq<sizeof...(Args)> {});
}

public:

template <typename ...Args> void setMethod(const std::function<Result(Args &&... args)> &method)
{
m_method = method;
}
};

class MethodsClass {

public:

Result doSomething(std::int32_t input, double output)
{
return Result::Result1;
}
};

int main()
{
**// This works fine**
MethodsClass methods;
Procedure <std::int32_t, double> procedure1;
procedure1.setMethod<std::int32_t, double>(std::bind(&MethodsClass::doSomething1, methods, _1, _2));

**// This end with compiler error std::tuple<int32_t,double &>::tuple': no appropriate default constructor available**

Procedure <std::int32_t, double &> procedure2;
procedure2.setMethod<std::int32_t, double &>(std::bind(&MethodsClass::doSomething2, methods, _1, _2));

return 0;
}

我知道为什么第二种情况不编译,消息很清楚,很明显必须初始化一个引用。但是在这种情况下该怎么做呢?如何初始化 std:tuple,如何以及在何处扩展参数包?我错过了一些东西,无法意识到是什么。

最佳答案

好吧,在 C++17 中这很容易。必须声明元组:

std::tuple<typename std::decay<Args>::type...> m_args;

然后所有的递归元组拆包都可以简单地删除并替换为:

std::apply(m_method, m_args);

关于c++ - 引用数据类型的可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48322724/

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