【发布时间】:2026-02-15 07:10:01
【问题描述】:
是否有这样的解决方案来循环使用模板化 int 参数的函数,而无需在任何时候使用 forIdx 使用新函数创建具有 body() 函数的新结构? C++20 中的模板化 lambda 看起来很有希望,但似乎不可能指定不会自动推导的模板参数。
struct LoopFunc {
template <int i>
void body() {
std::cout << i;
};
};
template<int i>
struct forIdx {
template<typename T>
static void loop(T&& func) {
func.body<i>();
forIdx<i - 1>::loop(func);
}
};
template<>
struct forIdx<-1> {
template<typename T>
static void loop(T&& func) {};
};
int main() {
forIdx<10>::template loop(LoopFunc{});
}
该函数用于创建元组元素的笛卡尔积。 DirectProduct 包含所有具有静态 generateAllElements() 函数的元素。
struct CrossProduct {
std::tuple<MockElement...> vals;
std::set<DirectProduct> result;
template <int num>
void body() {
if (result.empty()) {
for (const auto& e2 : std::get<num>(vals).generateAllElements()) {
DirectProduct tmp;
std::get<num>(tmp.vals) = e2;
result.insert(tmp);
}
}
else for (const DirectProduct& e1 : result)
for (const auto& e2 : std::get<num>(vals).generateAllElements()) {
DirectProduct tmp = e1;
std::get<num>(tmp.vals) = e2;
result.insert(tmp);
}
};
};
DirectProduct 在自己的generateAllElements() 函数中使用CrossProduct
std::set<DirectProduct> generateAllElements() const {
CrossProduct crossProduct{ };
forIdx<std::tuple_size<std::tuple<MockElement...>>::value - 1>::template loop(crossProduct);
return crossProduct.result;
};
【问题讨论】:
-
不要
constexpr或consteval功能适合您的需求? -
实际使用forIdx需要函数为void,但它也确实需要调用它的函数中的数据,所以我其实不知道自己尝试的能不能做到没有结构或某种 lambda。
-
我提供的解决方案似乎可以回答您的问题,但您的评论表明可能存在一些从显示的代码中看不到的额外限制。如果是这样,请编辑问题以澄清这一点。
-
这是创建元组元素的笛卡尔积,我能够简单地遍历元组的元素,但是当可能存在重复类型时访问和修改元组的特定索引是问题
-
那么这是一个 XY 问题,即您要解决的问题与您提出的问题不同。正如我所说,请编辑问题以明确您想要实现的目标;您根本没有提到任何关于叉积、元组或不同类型的内容。
标签: c++ templates variadic-templates template-meta-programming c++20