提问人:joysterling 提问时间:4/26/2023 最后编辑:joysterling 更新时间:5/1/2023 访问量:64
如何在递归函数中的模板上使用 operator[]
How to use operator[] on a template in a recursive function
问:
我正在尝试编写一些代码,这些代码将遍历某个未知深度的嵌套向量,并检查我们想要访问的索引是否在向量内;如果没有,我想添加空嵌套向量(同样,具有未知深度),直到我们到达这些索引。
例如,嵌套向量 like 在索引 [0, 0, 0], [0, 0, 1] 和 [0, 1, 0] 处具有数据。如果我们尝试访问索引 [0, 1, 1] 处的向量并将其设置为等于 “d”,则该函数会将向量扩展为 。{ { { "a" }, { "b" } }, { { "c" } } }
{ { { "a"}, { "b" } }, { { "c" }, { "d" } } }
我的想法是使用模板来实现这一点,就像这样(底部代码没有设置值,只是为了保持简单):
template<typename T>
void checkVector(T&& vec, vector<int> indexes, int counter = 0) {
// Base Case
if (counter > int(indexes.size()) - 1)
{
return;
}
// Add to vector
while (indexes[counter] > int(vec.size()) - 1)
{
vec.push_back({ {} });
}
// Recursive
checkVector(vec[indexes[counter]], indexes, counter++);
}
但是,递归部分不起作用,因为在模板上使用运算符 [] 会更改类型,因此它不会编译。所以我有两个问题:
- 如何索引到模板中并告诉编译器它也具有与模板 T 相同的属性?
- 这甚至是正确的方法吗?
谢谢大家!如果我对任何事情不清楚,请告诉我。
答:
0赞
Jarod42
4/26/2023
#1
使用常规时,所有分支都应该在模板中有效。if
您可以使用(或重载)来具有不同的路径。
但条件应该是 a(所以不能依赖于参数的值)。if constexpr
constexpr
例如,您可以执行以下操作:
template<typename T, typename U>
void setVectorAt(std::vector<T>& vec,
std::vector<std::size_t> indexes,
const U& value,
std::size_t counter = 0)
{
// Add to vector
vec.resize(std::max(1 + indexes[counter], vec.size()));
if constexpr (std::is_assignable_v<T, U>) {
vec[indexes[counter]] = value;
} else {
setVectorAt(vec[indexes[counter]], indexes, value, counter + 1);
}
}
0赞
joysterling
5/1/2023
#2
对于稍后查看此线程的任何人,我继续写下了 Remy 关于如何处理递归向量的建议:
template<typename T>
void checkVector(vector<T>& vec, vector<int> indexes, int counter = 0) {
if (counter > int(indexes.size()) - 1)
{
return;
}
while (indexes[counter] > int(vec.size()) - 1)
{
vec.push_back({});
}
checkVector(vec[indexes[counter]], indexes, counter + 1);
}
template<typename T>
void checkVector(T&& t, vector<int> indexes, int counter) {
return;
}
评论
T&&
vector<T>&
checkVector()
T
vector
vec[indexes[counter]]