C++ 11 std::map<K,V>类型具有一个emplace函数,许多其他容器也是如此.
std::map<int,std::string> m;
std::string val {"hello"};
m.emplace(1, val);
Run Code Online (Sandbox Code Playgroud)
此代码的工作方式与宣传的一样,std::pair<K,V>直接安排,但它会产生副本key并val发生.
是否可以将值类型直接置于地图中?我们能比调用中的参数更好emplace吗?
这是一个更彻底的例子:
struct Foo
{
Foo(double d, string s) {}
Foo(const Foo&) = delete;
Foo(Foo&&) = delete;
}
map<int,Foo> m;
m.emplace(1, 2.3, string("hello")); // invalid
Run Code Online (Sandbox Code Playgroud) 考虑功能:
template<typename T>
void printme(T&& t) {
for (auto i : t)
std::cout << i;
}
Run Code Online (Sandbox Code Playgroud)
或任何其他期望一个参数具有begin()/ end()启用类型的函数.
以下为什么违法?
printme({'a', 'b', 'c'});
当所有这些都合法时:
printme(std::vector<char>({'a', 'b', 'c'}));
printme(std::string("abc"));
printme(std::array<char, 3> {'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud)
我们甚至可以这样写:
const auto il = {'a', 'b', 'c'};
printme(il);
Run Code Online (Sandbox Code Playgroud)
要么
printme<std::initializer_list<char>>({'a', 'b', 'c'});
Run Code Online (Sandbox Code Playgroud) 通过转发就地构造,我指的是std :: allocator :: construct和各种emplace方法,例如std :: vector :: emplace_back.我只是发现在C++中转发的就地构造不能(无法?)利用列表初始化语法.结果,似乎人们永远无法就地构建聚合.我只是想确定转发的就地构造是否不支持列表初始化,因此也不支持聚合类型.这是由于语言的限制吗?有人可以提供有关此问题的标准吗?以下是一个例子:
虽然我们可以直接进行就地施工
int(*p)[3] = ...;
new(p) int[3]{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
我们不能做就地转发就像
std::allocator<int[3]> allo;
allo.construct(p, 1, 2, 3);
Run Code Online (Sandbox Code Playgroud) c++ object-construction language-lawyer c++11 list-initialization