如何使用向量的最后 N 个元素作为 C++ 中的函数参数?
How do I use the last N elements of a vector as a function parameters in C++?
我浏览这个网站已经有一段时间了,但刚刚注册。
我也使用了搜索,但似乎没有太大帮助。
这是:
当我对 C++ 很感兴趣时,我在 Internet 上提出了 "lazy evaluation" 的概念。我有兴趣创建类似 "lazy vector" 的东西,它是用带有 N 个参数和前 N 个向量元素的函数定义的。
但是,我目前遇到了这个问题。让我指出来:
template<typename T, typename... A>
class llazy
{
public:
llazy(const std::function<T(A...)>& func, A... args) : func(func), vec({args...}), numArgs(sizeof...(args))
{}
const T& operator[](size_t index)
{
unsigned short tmp = 1;
//Here I want to stray from 2 elements to pass to function and make the number at least like 0-4
std::vector<size_t> v;
for (unsigned short i = 0; i < numArgs; i++)
v.emplace_back(vec.size() - tmp++);
//As you can see here, there are no issues(if the vector has enough elements ofc) with these two
unsigned long long i = vec.size() - 2, j = vec.size() - 1;
while (vec.size() < index + 1)
//So how do I pass all the vec[v[0]], vec[v[1]], etc... elements to the "func"?
//Maybe there is another way to achieve this, however, this is the Python which makes me think this is possible
vec.emplace_back(func(vec[i++], vec[j++]));
if (vec.size() >= index + 1)
return vec[index];
}
private:
const unsigned char numArgs;
const std::function<T(A...)> func;
std::vector<T> vec;
};
using ullong = unsigned long long;
int main()
{
llazy<ullong, ullong, ullong> l(std::function<ullong(ullong, ullong)>([](ullong i, ullong j) { return i + j; }), 1, 1);
l[20];
l[50];
l[1000];
return 0;
}
提前感谢您的回答。
UPD:当然,可以将向量传递给函数,但是,这会使函数本身的可读性降低很多(例如,unsigned sum(unsigned, unsigned) 比 unsigned sum(std::vector )).
How do I use the last N elements of a vector as a function parameters
您不需要将这些元素放入临时向量中。
相反,经典的解决方案是使用带有 std::index_sequence
参数(和索引参数包)的单独函数(或 C++20 模板 lambda,如果你喜欢的话)。通过包扩展,您可以轻松地以一种或另一种方式从向量中提取最后 N 个元素。
像这样的东西会起作用:
template <typename F, std::size_t ...I>
auto make_tuple_seq(std::index_sequence<I...>, F &&func)
{
return std::tuple{func(I)...};
}
int main()
{
std::vector v = {1,2,3,4,5,6};
const int n = 3;
auto t = make_tuple_seq(std::make_index_sequence<n>{},
[&](std::size_t i) {return v[v.size() - n + i];});
// Prints `456`.
std::cout << std::apply([](int x, int y, int z){return x*100 + y*10 + z;}, t) << '\n';
}
根据您的需要调整此代码应该不难。
我浏览这个网站已经有一段时间了,但刚刚注册。 我也使用了搜索,但似乎没有太大帮助。
这是: 当我对 C++ 很感兴趣时,我在 Internet 上提出了 "lazy evaluation" 的概念。我有兴趣创建类似 "lazy vector" 的东西,它是用带有 N 个参数和前 N 个向量元素的函数定义的。
但是,我目前遇到了这个问题。让我指出来:
template<typename T, typename... A>
class llazy
{
public:
llazy(const std::function<T(A...)>& func, A... args) : func(func), vec({args...}), numArgs(sizeof...(args))
{}
const T& operator[](size_t index)
{
unsigned short tmp = 1;
//Here I want to stray from 2 elements to pass to function and make the number at least like 0-4
std::vector<size_t> v;
for (unsigned short i = 0; i < numArgs; i++)
v.emplace_back(vec.size() - tmp++);
//As you can see here, there are no issues(if the vector has enough elements ofc) with these two
unsigned long long i = vec.size() - 2, j = vec.size() - 1;
while (vec.size() < index + 1)
//So how do I pass all the vec[v[0]], vec[v[1]], etc... elements to the "func"?
//Maybe there is another way to achieve this, however, this is the Python which makes me think this is possible
vec.emplace_back(func(vec[i++], vec[j++]));
if (vec.size() >= index + 1)
return vec[index];
}
private:
const unsigned char numArgs;
const std::function<T(A...)> func;
std::vector<T> vec;
};
using ullong = unsigned long long;
int main()
{
llazy<ullong, ullong, ullong> l(std::function<ullong(ullong, ullong)>([](ullong i, ullong j) { return i + j; }), 1, 1);
l[20];
l[50];
l[1000];
return 0;
}
提前感谢您的回答。
UPD:当然,可以将向量传递给函数,但是,这会使函数本身的可读性降低很多(例如,unsigned sum(unsigned, unsigned) 比 unsigned sum(std::vector )).
How do I use the last N elements of a vector as a function parameters
您不需要将这些元素放入临时向量中。
相反,经典的解决方案是使用带有 std::index_sequence
参数(和索引参数包)的单独函数(或 C++20 模板 lambda,如果你喜欢的话)。通过包扩展,您可以轻松地以一种或另一种方式从向量中提取最后 N 个元素。
像这样的东西会起作用:
template <typename F, std::size_t ...I>
auto make_tuple_seq(std::index_sequence<I...>, F &&func)
{
return std::tuple{func(I)...};
}
int main()
{
std::vector v = {1,2,3,4,5,6};
const int n = 3;
auto t = make_tuple_seq(std::make_index_sequence<n>{},
[&](std::size_t i) {return v[v.size() - n + i];});
// Prints `456`.
std::cout << std::apply([](int x, int y, int z){return x*100 + y*10 + z;}, t) << '\n';
}
根据您的需要调整此代码应该不难。