为什么 C++ 使 std::initializer_list 的元素类型为常量?
Why does C++ make the element type of std::initializer_list const?
我通常使用 std::initializer_list<std::string>
,比如说 {"foo"s, "bar"s}
,来填充一个容器。
显然,std::initializer_list<std::string>
包含临时字符串,我可以将它们移动到容器中:
#include <string>
#include <list>
using namespace std::literals;
void f(std::initializer_list<std::string> il)
{
std::list<std::string> coll;
for (auto&& tmp_str : il)
{
coll.emplace_back(std::move(tmp_str)); // Why ok here?
}
}
int main()
{
f({"foo"s, "bar"s});
}
然而,根据cppref:
An object of type std::initializer_list is a lightweight proxy
object that provides access to an array of objects of type const T.
为什么C++要让std::initializer_list的元素类型为const?
Obviously, std::initializer_list<std::string>
contains temporary strings
是吗?允许将其实现为瘦代理。在这种情况下,它将引用原始实例 "foo"s
、"bar"s
.
... and I can move them into a container
我对此表示怀疑。 const
左值引用的 std::move()
产生... const
右值引用。这与作为可行候选者的移动构造函数不太匹配。
#include <iostream>
struct A {
A() { std::cout << "A()\n"; }
A(A&&) { std::cout << "A(&&)\n"; }
A(A const&) { std::cout << "A(const&)\n"; }
};
int main() {
const A a;
A b(std::move(a));
}
版画
A()
A(const&)
MSVC 2019 甚至警告:
Warning C26478 Don't use std::move on constant variables. (es.56).
另见
我通常使用 std::initializer_list<std::string>
,比如说 {"foo"s, "bar"s}
,来填充一个容器。
显然,std::initializer_list<std::string>
包含临时字符串,我可以将它们移动到容器中:
#include <string>
#include <list>
using namespace std::literals;
void f(std::initializer_list<std::string> il)
{
std::list<std::string> coll;
for (auto&& tmp_str : il)
{
coll.emplace_back(std::move(tmp_str)); // Why ok here?
}
}
int main()
{
f({"foo"s, "bar"s});
}
然而,根据cppref:
An object of type std::initializer_list is a lightweight proxy object that provides access to an array of objects of type const T.
为什么C++要让std::initializer_list的元素类型为const?
Obviously,
std::initializer_list<std::string>
contains temporary strings
是吗?允许将其实现为瘦代理。在这种情况下,它将引用原始实例 "foo"s
、"bar"s
.
... and I can move them into a container
我对此表示怀疑。 const
左值引用的 std::move()
产生... const
右值引用。这与作为可行候选者的移动构造函数不太匹配。
#include <iostream>
struct A {
A() { std::cout << "A()\n"; }
A(A&&) { std::cout << "A(&&)\n"; }
A(A const&) { std::cout << "A(const&)\n"; }
};
int main() {
const A a;
A b(std::move(a));
}
版画
A()
A(const&)
MSVC 2019 甚至警告:
Warning C26478 Don't use std::move on constant variables. (es.56).
另见