Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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+中生成大小从0到N的包+;其中N在编译时已知_C++_Variadic Templates - Fatal编程技术网

C++ 如何在C+中生成大小从0到N的包+;其中N在编译时已知

C++ 如何在C+中生成大小从0到N的包+;其中N在编译时已知,c++,variadic-templates,C++,Variadic Templates,背景:我编写了一个函数,它接受一些可调用的对象和一个元组,并将元组解压到可以传递给函数的参数包中。您可以想象,这涉及到一些模板递归。然而,我的大多数同事不是C++的本族语者,所以他们理解代码有麻烦,以及在函数被错误调用时得到的编译错误。 如果我可以生成一个大小为0到元组-1的包,我可以使用以下一个线性行: template <class Function, class... TupleArgs> auto UnpackTuple(Function fn, std::tuple<

背景:我编写了一个函数,它接受一些可调用的对象和一个元组,并将元组解压到可以传递给函数的参数包中。您可以想象,这涉及到一些模板递归。然而,我的大多数同事不是C++的本族语者,所以他们理解代码有麻烦,以及在函数被错误调用时得到的编译错误。 如果我可以生成一个大小为0到元组-1的包,我可以使用以下一个线性行:

template <class Function, class... TupleArgs>
auto UnpackTuple(Function fn, std::tuple<TupleArgs>&& t)
-> decltype(fn(std::declval<TupleArgs>()...)) {
  return fn(std::get<{my size_t pack}>(std::forward(t))...);
}
模板
自动解包元组(函数fn,std::tuple&&t)
->decltype(fn(std::declval()…){
返回fn(std::get(std::forward(t))…);
}

有什么可以替代“我的尺码包”的吗?我知道,如果我知道TupleArgs中的每种类型都是唯一的,我可以将它们组合在一起,但这是一个非常特殊的情况,对我来说没有任何用处。

看起来像是您在寻找的,它将完全满足您对
解包
的要求

也就是说,如果您出于某种奇怪的原因需要手动执行此操作(您可能不应该这样做,除非您希望执行与调用函数完全不同的操作), 几乎做你想要的(除了你的
size\u t
序列被包装在一个类型中,所以你需要一个额外的间接层次)。您可以在cppreference.com:1上看到如何在
std::apply
的示例实现中使用它

模板
constexpr decltype(自动)apply_impl(F&&F,元组&&t,std::index_序列)
{
返回std::invoke(std::forward(f),std::get(std::forward(t))…);
}
模板
constexpr decltype(自动)应用(F&&F、元组&&t)
{
返回应用程序(
标准:正向(f),
标准:正向(t),
std::make_index_sequence{}
);
}
由于您提到您仍在使用C++14,因此需要将
std::invoke
替换为正常的函数调用(但是,请保持
std::forward
,以防有人疯狂地实现
操作符()&&


1) (CC-BY-SA 3.0)

似乎是您正在寻找的,它将完全满足您对
解包
的要求

也就是说,如果您出于某种奇怪的原因需要手动执行此操作(您可能不应该这样做,除非您希望执行与调用函数完全不同的操作), 几乎做你想要的(除了你的
size\u t
序列被包装在一个类型中,所以你需要一个额外的间接层次)。您可以在cppreference.com:1上看到如何在
std::apply
的示例实现中使用它

模板
constexpr decltype(自动)apply_impl(F&&F,元组&&t,std::index_序列)
{
返回std::invoke(std::forward(f),std::get(std::forward(t))…);
}
模板
constexpr decltype(自动)应用(F&&F、元组&&t)
{
返回应用程序(
标准:正向(f),
标准:正向(t),
std::make_index_sequence{}
);
}
由于您提到您仍在使用C++14,因此需要将
std::invoke
替换为正常的函数调用(但是,请保持
std::forward
,以防有人疯狂地实现
操作符()&&


1)(CC-BSA 3)< /P>如果你坚持手工编写,添加另一个参数包<代码> siZixt…i < /> >和一个类型为“代码> STD::索引xxReals< /Calp>的虚拟参数,然后将代码> STD::MaxixDexxxSt*{}/Cux>进入新的参数。我的工作场所仍然在C++ 14:(关于STD:应用评论)如果您坚持手动编写,则添加另一个参数包<代码> siZixt…i <代码>和一个类型为“代码> STD::DexxOrthSuth的虚拟参数,然后将代码> STD::MaxixDexxxSt*{}/C++ >到新参数中。我的工作场所仍然在C++ 14:((关于STD:应用注释)这很酷-我太专注于寻找一种生成索引包的方法了,我甚至没有考虑让函数推断包。这很酷-我太专注于寻找一种生成索引包的方法了,我甚至没有考虑让函数推断包。

template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>)
{
    return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}

template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t)
{
    return apply_impl(
        std::forward<F>(f),
        std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{}
    );
}