MyTinySTL icon indicating copy to clipboard operation
MyTinySTL copied to clipboard

uninitialized_fill_n 的模板偏特化疑问,MyTinySTL的行为与标准库不同

Open woruyu opened this issue 1 year ago • 3 comments

调用链 1.mytinyStl vector(size_type n, const value_type& value) -> fill_init->mystl::uninitialized_fill_n(使用std::is_trivially_copy_assignable检查是否具有平凡的拷贝赋值运算符)->false 构造函数初始化,true 编译器自动生成的赋值运算符初始化 2.实际的c++标准库(ubuntu /usr/include/c++/12/bits/stl_vector.h) vector(size_type __n, const value_type& __value,...)->_M_fill_initialize -> std::__uninitialized_fill_n_a -> std::uninitialized_fill_n(__can_fill = is_copy_assignable<_ValueType>,这里只检查了是否有可用的拷贝赋值运算符,__is_trivial(_ValueType) 这个class是平凡的吗 ) -> ture, 值拷贝就是使用编译器自动生成的赋值运算符初始化, false 构造函数初始化。

逻辑: __is_trivial && is_copy_assignable 是否等价于 std::is_trivially_copy_assignable,答案是否定的__is_trivial很严格,需要有平凡的默认构造函数、拷贝构造函数、移动构造函数、拷贝赋值运算符、移动赋值运算符和析构函数(全是编译器自己生成的)。此外,它不能包含虚函数或虚基类,也不能有非平凡的非静态数据成员数,is_copy_assignable 只检查是否有可用的拷贝赋值运算符,而std::is_trivially_copy_assignable只检查是否具有平凡的拷贝赋值运算符,也就是拷贝赋值运算符必须是编译器自己生成的,而且class里面不包含虚函数等等的。

code: class A { int a; int c; int *b;

public: A() { std::cout << "consturctor A" << std::endl; }; A(const A &ra) { std::cout << "copy consturctor A" << std::endl; }; };

int main() { A a{}; mystl::vector<A> aa(10, a); }

difference: c++标准库会调用10次拷贝构造函数进行初始化, 而mytinySTL却调用10次值拷贝

woruyu avatar Feb 20 '24 02:02 woruyu