我想在几个数组上执行相同的操作,例如:
#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。周围有优雅的方式吗?
答案 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);
}