从一个值和一个大小创建递归函数参数列表
Create recursive function argument list from one value and a size
我的目的是创建一个大小为 n 的函数参数列表,这样我就可以将它传递给一个使用折叠表达式递归地将值相乘的助手。
我对如何将参数列表传递给助手有些困惑。
有没有办法在没有包表达式的情况下创建函数参数列表?
也许通过创建数组或元组?
这是我到目前为止的想法。
template<typename T, typename N>
T SmoothStart(const T& t, const N& n) {
static_assert(std::is_integral_v<N>, "templatized SmoothStart requires type of N to be integral.");
static_assert(n >= 0, "templatized SmoothStart requires value of N to be non-negative.");
if constexpr (n == 0) {
return 1;
}
if constexpr (n == 1) {
return t;
}
return SmoothStart_helper((t, ...)); //<-- obviously this doesn't work but it would be awesome to have!
}
template<typename T, typename... Args>
T SmoothStart_helper(Args&&... args) {
return (args * ...);
}
首先,如果您想使用折叠表达式,n
必须知道 compile-time。如果将其移至模板参数,获取大小为 N
的参数包的最简单方法是使用 std::make_index_sequence
:
// The helper has to be first so that the compiler can find SmoothStart_helper().
template<typename T, std::size_t... Is>
T SmoothStart_helper(const T& t, std::index_sequence<Is...>) {
// You were taking t by value here; I think you might want to still
// take it by reference
// Use the comma operator to simply discard the current index and instead
// yield t. The cast to void is to silence a compiler warning about
// Is being unused
return (((void) Is, t) * ...);
}
template<std::size_t N, typename T>
T SmoothStart(const T& t) {
// std::size_t is unsigned, so no need to check for N >= 0.
// We also don't need to special case when N == 1. The fold
// expression handles that case and just returns t
return SmoothStart_helper(t, std::make_index_sequence<N>{});
}
然后您可以像这样使用它:SmoothStart<N>(myThing);
。
我的目的是创建一个大小为 n 的函数参数列表,这样我就可以将它传递给一个使用折叠表达式递归地将值相乘的助手。
我对如何将参数列表传递给助手有些困惑。 有没有办法在没有包表达式的情况下创建函数参数列表? 也许通过创建数组或元组?
这是我到目前为止的想法。
template<typename T, typename N>
T SmoothStart(const T& t, const N& n) {
static_assert(std::is_integral_v<N>, "templatized SmoothStart requires type of N to be integral.");
static_assert(n >= 0, "templatized SmoothStart requires value of N to be non-negative.");
if constexpr (n == 0) {
return 1;
}
if constexpr (n == 1) {
return t;
}
return SmoothStart_helper((t, ...)); //<-- obviously this doesn't work but it would be awesome to have!
}
template<typename T, typename... Args>
T SmoothStart_helper(Args&&... args) {
return (args * ...);
}
首先,如果您想使用折叠表达式,n
必须知道 compile-time。如果将其移至模板参数,获取大小为 N
的参数包的最简单方法是使用 std::make_index_sequence
:
// The helper has to be first so that the compiler can find SmoothStart_helper().
template<typename T, std::size_t... Is>
T SmoothStart_helper(const T& t, std::index_sequence<Is...>) {
// You were taking t by value here; I think you might want to still
// take it by reference
// Use the comma operator to simply discard the current index and instead
// yield t. The cast to void is to silence a compiler warning about
// Is being unused
return (((void) Is, t) * ...);
}
template<std::size_t N, typename T>
T SmoothStart(const T& t) {
// std::size_t is unsigned, so no need to check for N >= 0.
// We also don't need to special case when N == 1. The fold
// expression handles that case and just returns t
return SmoothStart_helper(t, std::make_index_sequence<N>{});
}
然后您可以像这样使用它:SmoothStart<N>(myThing);
。