C++ 关于清理此终止条件的建议

C++ 关于清理此终止条件的建议,c++,c++11,C++,C++11,我一直在使用C++11 functional,以实现与python的itertools.combinations(输入,2)相同的功能,到目前为止,我的功能如下: 编辑按照@DavidRodríguez dribeas的建议删除外部lambda #include <iostream> #include <functional> #include <vector> using namespace std; template <class T> f

我一直在使用C++11 functional,以实现与python的itertools.combinations(输入,2)相同的功能,到目前为止,我的功能如下:

编辑按照@DavidRodríguez dribeas的建议删除外部lambda

#include <iostream>
#include <functional>
#include <vector>

using namespace std;

template <class T>
function<pair<T*, T*>()> combinations(vector<T> & input) {
  auto it1 = input.begin();
  auto end = input.end();
  auto it2 = next(it1);
  return [=]() mutable {
      if (it2 == end) {
        it1++;
        it2 = next(it1);
      }   
      if (it2 != end)
        return pair<T*,T*>(&(*it1), &(*it2++));
      return pair<T*,T*>(&*end, &*end);
    };  
};

int main (void) {
  vector<int> numbers{1,2,3,4,5,6};
  auto func = combinations(numbers);
  while ( true ) { 
    auto i = func();
    if (i.first == &*(numbers.end())) break;
    cout << *(i.first) << ',' << *(i.second) << endl;
  }

  return 0;
};
#包括
#包括
#包括
使用名称空间std;
模板
函数组合(向量和输入){
auto it1=input.begin();
自动结束=输入。结束();
自动it2=下一个(it1);
return[=]()可变{
如果(it2==结束){
it1++;
it2=下一个(it1);
}   
如果(it2!=结束)
返回对(&(*it1),&(*it2++);
返回对(&*结束,&*结束);
};  
};
内部主(空){
向量数{1,2,3,4,5,6};
自动功能=组合(数字);
虽然(正确){
自动i=func();
如果(i.first==&*(number.end())中断;
cout是我最喜欢的方法的文档和代码。下面是如何将该库用于您的示例:

#include <iostream>
#include <vector>
#include "combinations"

using namespace std;

int main (void) {
  vector<int> numbers{1,2,3,4,5,6};
  for_each_combination(numbers.begin(), numbers.begin()+2, numbers.end(),
           [](vector<int>::const_iterator b, vector<int>::const_iterator e)
           {
              if (b != e)
              {
                cout << *b;
                for (auto i = b+1; i != e; ++i)
                    cout << ',' << *i;
                cout << endl;
              }
              return false;
           });
}

1,2
1,3
1,4
1,5
1,6
2,3
2,4
2,5
2,6
3,4
3,5
3,6
4,5
4,6
5,6
#包括
#包括
#包括“组合”
使用名称空间std;
内部主(空){
向量数{1,2,3,4,5,6};
对于每个_组合(numbers.begin(),numbers.begin()+2,numbers.end(),
[](向量::常量迭代器b,向量::常量迭代器e)
{
如果(b!=e)
{

cout我发现Oliver Kowalke的协同程序库已经被Boosts同行评审所接受,并有望在下一个版本中被包含。有点仓促,我使用boost-dev repo的协同程序分支尝试了一下(https://gitorious.org/boost-dev/boost-dev)

g++-I path/to/boost-dev-std=c++11 test\u code.cpp-o run\u test\u code-static-L path/to/boost-dev/stage/lib/-lboost\u context

#include <boost/coroutine/all.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace boost;

template <typename T>
using coro_pairT_void = coroutines::coroutine<pair<T&,T&>(void)>;

template <typename T>
void combinations(typename coro_pairT_void<T>::caller_type & self, vector<T> & input ) { 
  for (auto it1 = input.begin(), itend = input.end(); it1 != itend; it1++) {
    for (auto it2 = std::next(it1); it2 != itend; it2++) {
      self(pair<T&, T&>(*it1,*it2));
    }   
  }
};

int main( void ) { 
  vector<int> numbers{1,2,3,4,5,6};
  coro_pairT_void<int> func(bind(combinations<int>, _1, numbers));
  for (auto it(begin(func)), itend(end(func)); it != itend; ++it) {
    cout << it->first << ',' << it->second << endl;
  }
  return 0;
};
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用名称空间boost;
模板
使用coro_pairT_void=coroutines::coroutine;
模板
void组合(typename coro_pairT_void::caller_type和self、vector和input){
对于(自动it1=input.begin(),itend=input.end();it1!=itend;it1++){
for(自动it2=std::next(it1);it2!=itend;it2++){
自我(配对(*it1,*it2));
}   
}
};
int main(void){
向量数{1,2,3,4,5,6};
coro_pairT_void func(绑定(组合,_1,数字));
对于(自动输入(开始(函数)),输入(结束(函数));输入!=输入;+输入){

你可以先简化代码(而不是条件)的一件事是删除外部lambda,它只用于一次执行…这样做没有意义。然后要简化
main
中的停止条件,你可以删除第二个lambda并使用适当的函子(或将lambda存储在函子中)提供完成测试(GoF迭代器模式)@SethCarnegie
g++-std=c++11 code.cpp
在@GarethA.Lloyd上有几个迭代组合的示例,在您编辑它并取出错误代码之前,我发表了评论。在为每个组合测试函数时,我有点惊讶,它实际上会将向量中的数据和周围的交换元素弄乱。我非常惊讶就像OP方法一样,我可以想象一个更一般的解决方案,将r作为参数传递(或者可能是一个整数模板)因此,函数组合将返回某种生成器,在每次调用时提供指向下一个r组合的迭代器的r元组。它根本不会触及数据,因此可以用于向量中的重对象。它也可能更有效?(我不确定)。你觉得这种方法怎么样?@ThomasPetit:这看起来确实是另一种可行的接口。我认为必须对其进行编码和测试,才能在知情的情况下决定哪个接口/实现最有效。在我的实现中,移动和交换是专用的(而不是复制)假设这样的事情通常足够有效。也就是说,我们当然可以举出不正确的例子。但我们也可以通过传递一系列迭代器或对原始重对象的引用来解决这样的问题,从而完全实现您的要求。
#include <boost/coroutine/all.hpp>
#include <boost/bind.hpp>
#include <boost/range.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace boost;

template <typename T>
using coro_pairT_void = coroutines::coroutine<pair<T&,T&>(void)>;

template <typename T>
void combinations(typename coro_pairT_void<T>::caller_type & self, vector<T> & input ) { 
  for (auto it1 = input.begin(), itend = input.end(); it1 != itend; it1++) {
    for (auto it2 = std::next(it1); it2 != itend; it2++) {
      self(pair<T&, T&>(*it1,*it2));
    }   
  }
};

int main( void ) { 
  vector<int> numbers{1,2,3,4,5,6};
  coro_pairT_void<int> func(bind(combinations<int>, _1, numbers));
  for (auto it(begin(func)), itend(end(func)); it != itend; ++it) {
    cout << it->first << ',' << it->second << endl;
  }
  return 0;
};