C ++如何将参数包存储为变量 [英] C++ How to store a parameter pack as a variable

查看:98
本文介绍了C ++如何将参数包存储为变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我无法存储参数包,这是设计的示例代码:

  template< ; typename Func,typename ... Args> 
void handleFunc(Func func,Args& ... args){
struct nest {
Func nestFunc;
Args ... nestArgs; // I DONT KNOW WHAT TO DO HERE
void setup(Func func,Args ... args){
nestFunc = func;
nestArgs =(args)...; //我可以在这里设置
}
//稍后我将转发这个并运行带有参数的函数
unsigned process(){
nestFunc(std :: forward< ; Args(nestArgs)...); // USE IT HERE
return 0;
}
};
nest * myNest;
myNest-> setup(func,(args)...);
}

这是一个涉及到问题的例子,我需要存储后来的参数在我的nest结构中调用。此外,如果你有一个解决方案来存储它,但设置它不同于我的,请也让我知道这一点。感谢。

解决方案

您必须使用 :: std :: tuple& 来存储它。但问题是如何解开它,当你需要它。因此,你需要使用一种称为'indices'的技术。



所以,这里是一个链接到一个地方,我做了大约你想要做什么。这里最相关的类型是 suspended_call



https://bitbucket.org/omnifarious/sparkles/src/tip/sparkles/deferred.hpp?at=default




稍后,我将提取最相关的位,并将它们放在您的代码中。 b

此行

  auto saved_args = :: std :: make_tuple(:: std :: move(args)...) 

将参数保存到元组中。我使用 :: std :: move ,我认为这是正确的事情。但是可能我错了,我应该使用 :: std :: forward 。我从来没有明确除了信令意图之外的确切差异。



实际上使用保存的参数调用的代码可以找到这里。现在代码是相当具体的我正在做什么。实现索引技巧的位涉及创建一组整数,映射到索引以作为 :: std :: get< I> 模板的参数。一旦你有了这个整数,你可以使用它扩展对 :: std :: get 的调用,以获取所有的元组元素作为单独的参数。



我会尝试以相对直接的方式提供代码:

  #include< tuple> 
#include< cstddef>
#include< string>
#include< utility>

template< :: std :: size_t ...指数>
struct indices {};

template< :: std :: size_t N,:: std :: size_t ... Is>
struct build_indices:build_indices< N-1,N-1,Is ...>
{};

template< :: std :: size_t ... Is>
struct build_indices< 0,Is ...> :indices< Is ...>
{};

template< typename FuncT,typename ArgTuple,:: std :: size_t ... Indices>
auto call(const FuncT& f,ArgTuple&& args,const indices< Indices ...>&)
- > decltype(f(:: std :: get< Indices>(:: std :: forward< ArgTuple>(args))...))
{
return :: std :: move (:: std :: get< Indices>(:: std :: forward< ArgTuple>(args))...));
}

template< typename FuncT,typename ArgTuple>
auto call(const FuncT& f,ArgTuple&& args)
- > decltype(call(f,args,
build_indices< :: std :: tuple_size< ArgTuple> :: value> {}))
{
const build_indices< :: std :: tuple_size< ArgTuple> :: value>指数;

return :: std :: move(call(f,:: std :: move(args),indices));
}

int myfunc(:: std :: string name,const unsigned int foo)
{
return 0;
}

int foo(:: std :: tuple< :: std :: string,const unsigned int> saved_args)
{
return call(myfunc, :: std :: move(saved_args));
}

很多这样的代码是从本指南上的技巧



此外,这是一个样例你将不得不略微适应你的具体情况。基本上,只需调用调用(nestFunc,saved_args)某处。


At the moment I am having trouble trying to store a parameter pack, this is example code of the design:

template<typename Func, typename... Args>
void handleFunc(Func func, Args&&... args) {
    struct nest {
        Func nestFunc;
        Args... nestArgs; // I DONT KNOW WHAT TO DO HERE
        void setup(Func func, Args... args) {
            nestFunc = func;
            nestArgs = (args)...; // SO I CAN SET IT HERE
        }
        // Later I will forward this and run the function with its arguments
        unsigned process() {
            nestFunc(std::forward<Args>(nestArgs)...); // USE IT HERE
            return 0;
        }
    };
    nest* myNest;
    myNest->setup(func, (args)...);
}

This is an example of everything involved for the problem, I need to store the arguments for later invoke in my nest struct. Also, if you have a solution to store it but to set it is different to mine, please also let me know about that too. Thanks.

解决方案

You have to use ::std::tuple<Args...> to store it. But then the question is how to unpack it when you need it. For that you need to use a technique called 'indices'.

So, here is a link to a place where I've done approximately what you're looking to do. The most relevant class here that's sort of the centerpiece is suspended_call.

https://bitbucket.org/omnifarious/sparkles/src/tip/sparkles/deferred.hpp?at=default

In just a bit, I'll extract the most relevant bits and put them in terms of your code.

This line:

auto saved_args = ::std::make_tuple(::std::move(args)...);

saves the arguments into a tuple. I used ::std::move there, and I think that's the right thing to do. But it's possible I'm wrong and I should use ::std::forward. I've never been clear on the exact difference aside from signaling intent.

The code that actually does the call with the saved arguments can be found here. Now that code is fairly specific to exactly what I'm doing. The bit that implements the indices trick involves creating a pack of integers that maps to the indices to use as arguments the ::std::get<I> template. Once you have this pack of integers, you can then use it to expand the call to ::std::get to get all the tuple elements as individual arguments.

I'll try to come up with code that does that in a relatively straightforward way:

#include <tuple>
#include <cstddef>
#include <string>
#include <utility>

template < ::std::size_t... Indices>
struct indices {};

template < ::std::size_t N, ::std::size_t... Is>
struct build_indices : build_indices<N-1, N-1, Is...>
{};

template < ::std::size_t... Is>
struct build_indices<0, Is...> : indices<Is...>
{};

template <typename FuncT, typename ArgTuple, ::std::size_t... Indices>
auto call(const FuncT &f, ArgTuple &&args, const indices<Indices...> &)
   -> decltype(f(::std::get<Indices>(::std::forward<ArgTuple>(args))...))
{
   return ::std::move(f(::std::get<Indices>(::std::forward<ArgTuple>(args))...));
}

template <typename FuncT, typename ArgTuple>
auto call(const FuncT &f, ArgTuple &&args)
     -> decltype(call(f, args,
                      build_indices< ::std::tuple_size<ArgTuple>::value>{}))
{
    const build_indices< ::std::tuple_size<ArgTuple>::value> indices;

    return ::std::move(call(f, ::std::move(args), indices));
}

int myfunc(::std::string name, const unsigned int foo)
{
   return 0;
}

int foo(::std::tuple< ::std::string, const unsigned int> saved_args)
{
   return call(myfunc, ::std::move(saved_args));
}

A lot of this code was borrowed from this page on the indices trick.

Also, that's sort of a sample that you will have to adapt slightly to your specific situation. Basically, just call call(nestFunc, saved_args) somewhere.

这篇关于C ++如何将参数包存储为变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆