对引用的迭代?

时间:2012-02-07 11:51:32

标签: c++ for-loop c++11 pass-by-reference

我想在几个数组上执行相同的操作,例如:

#include<vector>
#include<algorithm>
int main(void){
    std::vector<double> a, b;
    for(auto& ab:{a,b}) std::sort(ab.begin(),ab.end()); // error 
}

此代码失败,因为auto&是const-reference。周围有优雅的方式吗?

3 个答案:

答案 0 :(得分:7)

我认为问题在于它有点像将临时绑定绑定到非const引用。那里没有“具体”的集合,所以它有点像临时的。

如果你有一个临时向量,它将绑定到一个const引用,但不是一个非const引用。

我也认为这不会对你正在做的事情起作用,但这应该有效:

#include<vector> 
#include<algorithm> 
int main(void)
{     
    std::vector<double> a, b;     
    for(std::vector<double>* ab:{&a,&b}) 
      std::sort(ab->begin(),ab->end()); // or begin(*ab),end(*ab)
} 

和auto也可以。

答案 1 :(得分:2)

  

此代码失败,因为auto&amp;是一个const-reference。 [强调我的]

你的推理不成立。在基于范围的for循环中,您声明的内容(此处为auto& ab绑定到范围表达式(此处为{a,b })。相反,ab将从范围的元素初始化,而不是范围本身。

相反,错误源于使用参数std::sort / ab.begin()调用ab.end(),这可以通过评论循环体轻松地见证。正如RMartinho指出的那样,std::initializer_list<std::vector<double>>的元素是不可变的,你不能使用移动对const容器(std::sort shuffles元素进行排序,不能分配给const 1}}元素)。

假设你想(独立地)对两个向量进行排序,你可以这样做:

for(auto& ab: { std::ref(a), std::ref(b) })
    std::sort(std::begin(ab.get()), std::end(ab.get()));

请注意,根据模板参数扣除规则,auto&在这里没问题,auto将推断为const std::reference_wrapper<std::vector<double>>,产生std::reference_wrapper<std::vector<double>> const&作为ab的类型}。

答案 2 :(得分:0)

我认为CashCows解决方案很好。只是为了显示不同的方式:您还可以使用可变参数模板来解决此问题。

#include <vector>
#include <algorithm>

using namespace std;

void mysort() {} // termination version

template<typename Arg1, typename... Args>
void mysort(Arg1 &arg1, Args&... args )
{
    sort(arg1.begin(), arg1.end());
    mysort(args...);
}

int main(void)
{
    vector<double> a, b;
    mysort(a, b);
}

@CashCow:可以将算法作为参数传递,但由于使用了decltype,它有点难看:

#include <vector>
#include <algorithm>

using namespace std;

template<typename Algo>
void mysort(Algo algo) {} // termination version

template<typename Algo, typename Arg1, typename... Args>
void mysort(Algo algo, Arg1 &arg1, Args&... args )
{
    algo(arg1.begin(), arg1.end());
    mysort(algo, args...);
}

int main(void)
{
    vector<double> a, b;
    mysort(&sort<decltype(a.begin())>, a, b);
}