你猜对了。std::initializer_list
元素总是const
(这使得sort()
荷兰国际集团不可能,因为sort()
是一个非const
成员函数)及其元素总是被复制(这将使sort()
- 即使它们没有意义,它们也毫无意义const
)。来自 [dcl.init.list],强调我的:
类型的对象std::initializer_list<E>
从初始化列表构造,就像实现一样
分配了一个由 N 个类型元素组成的临时数组const E,其中 N 是元素的数量
初始化列表。该数组的每个元素是复制初始化与初始化器的相应元素
列表,以及std::initializer_list<E>
构造对象来引用该数组。[ Note:构造函数
或为副本选择的转换函数应在初始化程序的上下文中可访问(第 11 条)
列表。——尾注]如果需要缩小转换来初始化任何元素,则该程序是
格式不正确。[ 例子:
struct X {
X(std::initializer_list<double> v);
};
X x{ 1,2,3 };
初始化的实现方式大致相当于:
const double __a[3] = {double{1}, double{2}, double{3}};
X x(std::initializer_list<double>(__a, __a+3));
假设该实现可以构造一个initializer_list
带有一对指针的对象。-结尾
例子 ]
没有办法使它们成为非 const 或非复制的。指针解决方案的工作原理:
for (auto l : {&a, &b, &c}) l->sort();
因为它是pointer那是 const,而不是它指向的元素。另一种选择是编写一个可变参数函数模板:
template <typename... Lists>
void sortAll(Lists&&... lists) {
// before C++17
using expander = int[];
expander{0, (void(lists.sort()), 0)...};
// C++17 or later
(lists.sort(), ...);
}
sortAll(a, b, c);
我想,您还可以编写一个助手将您的列表包装到一个数组中reference_wrapper
to list<int>
(因为你不能有一组引用),但这可能更令人困惑而不是有帮助:
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()