问题描述
我试图遍历多个 std :: list
s,并对它们进行排序。这是天真的方法:
I am trying to iterate over a number of std::list
s, sorting each of them. This is the naive approach:
#include<list>
using namespace std;
int main(void){
list<int> a,b,c;
for(auto& l:{a,b,c}) l.sort();
}
生产
aa.cpp:5:25: error: no matching member function for call to 'sort'
for(auto& l:{a,b,c}) l.sort();
~~^~~~
/usr/bin/../lib64/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_list.h:1586:7: note:
candidate function not viable: 'this' argument has type 'const
std::list<int, std::allocator<int> >', but method is not marked const
sort();
^
/usr/bin/../lib64/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_list.h:1596:9: note:
candidate function template not viable: requires 1 argument, but 0 were
provided
sort(_StrictWeakOrdering);
^
1 error generated.
我正确地猜到了括号初始化器正在创建这些列表的副本吗?有没有办法不复制它们,并使它们在循环内可修改? (除了列出指向它们的指针,这是我当前的解决方法)。
Am I correctly guessing that brace-initializer is creating copy of those lists? And is there a way to not copy them, and make them modifiable inside the loop? (other than making list of pointers to them, which is my current workaround).
推荐答案
您的猜测正确。 std :: initializer_list
元素始终为 const
(这使得 sort()
使其不可能,因为 sort()
是非< const
成员函数),其元素始终复制(这会使 sort()
-即使它们不是 const
也使它们毫无意义)。从[dcl.init.list]中,重点突出:
You are guessing correctly. std::initializer_list
elements are always const
(which makes sort()
ing them impossible, as sort()
is a non-const
member function) and its elements are always copied (which would make sort()
-ing them meaningless even if they weren't const
). From [dcl.init.list], emphasis mine:
struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
初始化将以大致等同于以下方式的方式实现:
The initialization will be implemented in a way roughly equivalent to this:
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
假设实现可以构建 initializer_list
有一对指针的对象。 -结束
的示例]
assuming that the implementation can construct an initializer_list
object with a pair of pointers. —end example ]
没有办法使它们成为非常量或非常量-复制。指针解决方案有效:
There is no way to make them non-const or non-copied. The pointer solution works:
for (auto l : {&a, &b, &c}) l->sort();
因为它是常量的 pointer ,而不是它指向的元素。另一种选择是编写可变参数函数模板:
because it's the pointer that's const, not the element it's pointing to. The other alternative would be to write a variadic function template:
template <typename... Lists>
void sortAll(Lists&&... lists) {
using expander = int[];
expander{0, (void(lists.sort()), 0)...};
}
sortAll(a, b, c);
我想,您还可以编写一个帮助程序,将您的列表包装到<$ c数组中$ c> reference_wrapper 到 list< int>
(因为您不能有多个引用数组),但这可能比帮助更令人困惑:
You could also, I guess, write a helper to wrap your lists into an array of reference_wrapper
to list<int>
(since you can't have an array of references), but this is probably more confusing than helpful:
template <typename List, typename... Lists>
std::array<std::reference_wrapper<List>, sizeof...(Lists) + 1>
as_array(List& x, Lists&... xs) {
return {x, xs...};
}
for (list<int>& l : as_array(a, b, c)) { // can't use auto, that deduces
l.sort(); // reference_wrapper<list<int>>,
} // so would need l.get().sort()
这篇关于基于括号的非常量值的基于范围的初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!