如果我通过我的GCC 4.7快照传递以下代码,它会尝试将unique_ptrs 复制到向量中.
#include <vector>
#include <memory>
int main() {
using move_only = std::unique_ptr<int>;
std::vector<move_only> v { move_only(), move_only(), move_only() };
}
Run Code Online (Sandbox Code Playgroud)
显然,因为std::unique_ptr不可复制而无法工作:
错误:使用已删除的函数'std :: unique_ptr <_Tp,_Dp> :: unique_ptr(const std :: unique_ptr <_Tp,_Dp>&)[with _Tp = int; _Dp = std :: default_delete; std :: unique_ptr <_Tp,_Dp> = std :: unique_ptr]'
GCC是否正确尝试从初始化列表中复制指针?
我允许将元素移出std::initializer_list<T>?
#include <initializer_list>
#include <utility>
template<typename T>
void foo(std::initializer_list<T> list)
{
for (auto it = list.begin(); it != list.end(); ++it)
{
bar(std::move(*it)); // kosher?
}
}
Run Code Online (Sandbox Code Playgroud)
由于std::intializer_list<T>需要特殊的编译器注意并且没有像C++标准库的普通容器那样的值语义,所以我宁愿安全而不是抱歉并且问.
我对设计有一些疑问std::initializer_list.我在[support.initlist]中找不到答案.
为什么它有一个显式定义的默认构造函数?
为什么这个构造函数不是constexpr?
为什么方法size()不是constexpr?
为什么没有特质给出大小initializer_list(如专精std::tuple_size)?
为什么不可能静态访问其元素(如专业化std::get)?
sizeof适用于什么时会发生什么initializer_list?
第一部分 :
std::initializer_list是C++ 11的一个非常有用的功能,所以我想知道它是如何在标准库中实现的.从我在这里读到的,编译器创建一个类型的数组,T并给出指向initializer_list<T>.
它还指出复制一个initializer_list会创建一个引用相同数据的新对象:为什么会这样?我猜它也是:
initializer_listinitializer_list第二部分 :
来自std::vector构造函数的许多在线参考资料中的一个:
vector (initializer_list<value_type> il,
const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)
(6)初始化列表构造函数
构造一个容器,其中包含il中每个元素的副本,顺序相同.
我对移动语义还不满意,但是不能把数据il移到vector?我不知道std::vectorIIRC 的深度实现它使用普通的数组.
可能重复:
initializer_list和移动语义
在这段代码中:
#include <vector>
#include <initializer_list>
template<typename T>
class some_custom_container : public std::vector<T>
{
public:
some_custom_container(const std::initializer_list<T>& contents)
{
for (auto& i : contents)
this->emplace_back(std::move(i));
}
};
class test_class
{};
int main()
{
test_class a;
some_custom_container<test_class> i = { a, test_class(), a };
}
Run Code Online (Sandbox Code Playgroud)
如果我理解了它,那么所有对象{ a, test_class(), a }都是安全构造的:复制了命名对象,并移动了未命名的对象来构造initializer_list.之后,initializer_list通过引用传递给它some_custom_container的构造函数.
然后,为了避免无用的doble-copies,我移动所有这些来填充向量.
这个构造函数安全吗?我的意思是,在一个奇怪的情况下,例如如果T被评估为参考&或&&,那么向量是否总是充满(包含它的安全对象)?
如果是这种情况,为什么initializer_liststl容器的构造函数实现没有以这种方式实现?据我所知,他们的构造函数复制并且不移动内容.
当我执行以下代码时,在和AAA之间调用了两次 的复制构造函数。boofoo
我只是想知道他们每个人的确切名字是什么时候。
代码:
#include <iostream>
#include <vector>
class AAA
{
public:
AAA(void)
{
std::cout<<"AAA ctor"<<std::endl;
}
AAA(const AAA& aRhs)
{
std::cout<<"AAA copy ctor"<<std::endl;
}
AAA(AAA&& aRhs) = default;
};
void foo(std::vector<AAA>&& aVec)
{
std::cout<<"----foo"<<std::endl;
}
void boo(const AAA& a)
{
std::cout<<"----boo"<<std::endl;
foo({a});
std::cout<<"----boo"<<std::endl;
}
int main(void)
{
AAA a;
boo(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
AAA ctor
----boo
AAA copy ctor
AAA copy ctor
----foo
----boo
Run Code Online (Sandbox Code Playgroud)