Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何划分参数包?_C++_Templates_C++11 - Fatal编程技术网

C++ 如何划分参数包?

C++ 如何划分参数包?,c++,templates,c++11,C++,Templates,C++11,我想写一个函数模板,apply,它接收一些函数f,一个整数I,以及一个参数包apply需要解压参数并对其应用f,除了ith参数,pi。对于pi,它需要调用一些其他函数g,然后将其作为参数传递给f 似乎我需要一种方法将参数包划分为左侧、Ith参数和右侧。这可能吗?代码: template<int i, typename Function, typename... Parms> void apply(Function f, Parms... parms) { auto lhs =

我想写一个函数模板,
apply
,它接收一些函数
f
,一个整数
I
,以及一个参数包
apply
需要解压参数并对其应用
f
,除了
i
th参数,
pi
。对于
pi
,它需要调用一些其他函数
g
,然后将其作为参数传递给
f

似乎我需要一种方法将参数包划分为左侧、
I
th参数和右侧。这可能吗?代码:

template<int i, typename Function, typename... Parms>
  void apply(Function f, Parms... parms)
{
  auto lhs = // what goes here?
  auto pi =  // what goes here?
  auto rhs = // what goes here?

  f(lhs..., g(pi), rhs...);
}
模板
无效应用(函数f,参数…参数)
{
auto lhs=//这里是什么?
auto pi=//这里是什么?
auto rhs=//这里是什么?
f(左侧…,g(pi),右侧;
}

好了,开始吧!它真的很难看,但我不能马上想出一个更好的版本;)大部分内容是bog标准模板专门化。最大的问题是创建一个适当大小的整数列表。我似乎记得我提出了一个很好的版本,但不知何故我记不起我做了什么。享受吧

#include <iostream>
#include <utility>

// printing the values
void print_args() {}
template <typename F> void print_args(F f) { std::cout << f; }
template <typename F, typename... T>
void print_args(F f, T... args)
{
    std::cout << f << ", ";
    print_args(args...);
}

// the function object to be called:
struct Functor
{
    template <typename... T>
    void operator()(T... args)
    {
        std::cout << "f(";
        print_args(args...);
        std::cout << ")\n";
    }
};

// conditionally apply g():
template <typename T> T g(T value) { return 1000 + value; }
template <int i, int j, typename T>
typename std::enable_if<i != j, T>::type forward(T t) { return t; }
template <int i, int j, typename T>
typename std::enable_if<i == j, T>::type forward(T t) { return g(t); }

// create a series of integers:
template <int... Values> struct values {};

template <int Add, typename> struct combine_values;
template <int Add, int... Values>
struct combine_values<Add, values<Values...>>
{
    typedef values<Values..., Add> type;
};

template <int Size> struct make_values;
template <> struct make_values<0> { typedef values<> type; };
template <int Size>
struct make_values
{
    typedef typename combine_values<Size, typename make_values<Size -1>::type>::type type;
};

// applying f(t...) except for ti where g(ti) is called
template <int i, int... Values, typename Function, typename... T>
void apply_aux(values<Values...>, Function f, T... t)
{
    f(forward<i, Values>(t)...);
}

template <int i, typename Function, typename... T>
void apply(Function f, T... t)
{
    apply_aux<i>(typename make_values<sizeof...(T)>::type(), f, t...);
}

int main()
{
    apply<3>(Functor(), 1, 2, 3, 4, 5, 6, 7, 8);
    apply<4>(Functor(), 1, 2, 3, 4, 5, 6, 7, 8);
    apply<5>(Functor(), 1, 2, 3, 4, 5, 6, 7, 8);
}
#包括
#包括
//打印值
无效打印参数(){}

模板void print_args(F){std::couti不久前确实编写了类似的代码。因此,请尝试以下代码:

template<unsigned N, unsigned M>
struct call_up_impl{
    template<class Func, class Mutator, class Tuple, class... Args>
    static void do_call(const Func& func, const Mutator& mutator, const Tuple& args, Args&&... unpacked_args) {
        call_up_impl<N-1, M>::do_call(func, mutator, args, std::get<N-1>(args), std::forward<Args>(unpacked_args)...);
    }
};

template<unsigned M>
struct call_up_impl<0, M> {
    template<class Func, class Mutator, class Tuple, class... Args>
    static void do_call(const Func& func, const Mutator&, const Tuple&, Args&&... unpacked_args) {
        func(std::forward<Args>(unpacked_args)...);
    }
};
template<unsigned M>
struct call_up_impl<M, M> {
    template<class Func, class Mutator, class Tuple, class... Args>
    static void do_call(const Func& func, const Mutator& mutator, const Tuple& args, Args&&... unpacked_args) {
        call_up_impl<M-1, M>::do_call(func, mutator, args, mutator(std::get<M-1>(args)), std::forward<Args>(unpacked_args)...);
    }
};
template<int i, typename Function, typename... Parms>
void apply(Function f, Parms... parms) {
      std::tuple<Parms...> t(parms...);
      call_up_impl<std::tuple_size<decltype(t)>::value, i + 1>::do_call(f, &g, t);
}

可能会避免元组带来的大部分开销。正确转发
std::get
调用的结果会更好,但我现在太累了,无法完成写操作。

pi在math.h中作为m_pi提供。其余部分不确定,你能用更少的省略号发布代码吗?@HansPassant我想OP的意思是<代码>参数> <代码> @代码> pI<代码> @ HaspSaseTc++现在完全损坏了:你不需要再写所有的代码了!省略号实际上是代码,正在执行!@ HSPSPANTANT: LOL!谢谢你的笑!”DeTim-U.HL:YUP C++ 11是如此先进,它知道程序员希望程序做什么。从现在开始,所有新的C++代码。将如下所示:
intmain(intargc,char**argv){…}
我认为这看起来更复杂,而且还依赖于
std::tuple
来完成所有工作!当然,我还使用了一个标准类(
std::enable_if
)但和
std::tuple
相比,
std::enable_if
的实现是微不足道的。我的很多代码实际上也在应用该操作并打印结果。@DietmarKühl:我不同意看起来更复杂的部分。如果我们绑定到C++11,依赖
std::tuple
有什么问题只是因为无论如何都要使用可变模板?(此外,可变模板实现必要的元组操作也很容易)。那么问题出在哪里呢?这两种解决方案都很有趣。感谢您提供它们。不过,我对c++11中没有更直接的解决方案感到失望。最终使用了这个解决方案。谢谢!
template<int i, typename Function, typename... Parms>
void apply(Function f, Parms&&... parms) {
      std::tuple<Parms&&...> t(std::forward<Parms>(parms)...);
      call_up_impl<std::tuple_size<decltype(t)>::value, i + 1>::do_call(f, &g, t);
}