我正在尝试使用 STL 的风格创建一个函数来生成可变数量的输入范围的笛卡尔积。我的基本格式是该函数接受固定范围和输出范围的开头,然后是双向输入迭代器的可变数量。
template <
typename BidirectionalIterator,
typename OutputIterator,
typename... Args
>
void cartesian_product(
BidirectionalIterator first,
BidirectionalIterator last,
OutputIterator result,
Args&&... args
);
我的想法是args
是我做了一个tuple
出来,然后我迭代它tuple
来提取元素。这需要我遵循几个基本步骤:
- Make a
tuple
from args
- 取消引用新创建的每个迭代器
tuple
- 递增每个迭代器
tuple
按顺序,以便我们获得范围内值的所有可能组合。
详细说明第 3 步:如果我们有两个集合 A = {0, 1} 和 B = {2, 3},则笛卡尔积 A x B = {(0, 2), (0, 3), (1, 2), (1, 3)}。
我可以做第一步:
auto arg_tuple = std::make_tuple(std::forward<Args>(args)...);
第二步,我不太确定。我想我会以某种方式push_back
元素到临时元组,然后设置*result
等于该临时元组。我受到了一点启发ostream
实现了这一点,所以我认为这可能会派上用场:
template <typename Tuple, typename T>
auto operator<<(const Tuple &lhs, const T &rhs)
-> decltype(std::tuple_cat(lhs, std::make_tuple(rhs)))
{
return std::tuple_cat(lhs, std::make_tuple(rhs));
}
第三步可能非常简单。我可以结合这样的东西:
template <typename T>
auto pre_increment(T &x) -> decltype(++x) {
return ++x;
}
3,000 次实施之一for_each
for a tuple
就在这里。
很可能我没有正确利用 C++14 来实现这一点。到目前为止,我所接受的教育完全是 C++11 中不太困难的部分。
如果你想推荐我使用boost::fusion
为此,谢谢,但我不想使用它。