From 5587cbfb2b068e8caf658ad20b98140c48145dfc Mon Sep 17 00:00:00 2001 From: David1West <116949204+David1West@users.noreply.github.com> Date: Sun, 15 Jan 2023 16:34:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=B9construct=E7=9A=84=E5=8F=AF=E5=8F=98?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E6=A8=A1=E6=9D=BF=E8=BF=9B=E8=A1=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (新手观点,大佬轻喷) 目前版本的construct的可变参数模板版本并不能有效地让自定义类通过construct来创建对象,如: 对于如下代码: ~~~ #include #include"allocator.h" using namespace std; class A{ public: A(int a):m(a),n(0.0){ cout<<"int constructor"< a; A* p1=a.allocate(10); a.construct(p1,10);//construct的模板参数包匹配的类型为int,相当于construct(A*,int && args) a.construct(p1,10,1.0);//相当于construct(A*,int &&,double &&),此时无法调用自己写的forward a.deallocate(p1); return 0; } ~~~ 如果construct.h中存在 template void construct(T* ,Args && ...args),那么会导致a.construct(p1,10)无法正确匹配到util.h中的construct(Ty1 *,const Ty2&value),a.construct(p1,10,1.0)会报no matching function的错误 如果将上述代码从construct.h中删掉,那么第20行代码会调用A(int)构造函数,打印出"int constructor" 第21行代码则会因为没有对应版本的forward\而报错 但是std::allocator是可以实现上述功能的: ~~~ #include #include"allocator.h" using namespace std; class A{ public: A(const int& a):m(a),n(0.0){ cout<<"int constructor"< a; A* p1=a.allocate(10); int b=10; a.construct(p1,20);//打印"int constructor" a.construct(p1,10,1.0);//打印"int and double constructor" cout<m< template void allocator::construct(Other* p,Args && ... args){ ::new ((void*)p) Other(mstl::forward(args)...); } ~~~ 事实上,无需提供三个版本的construct()(通过调用util.h里的重载的construct函数),在allocator里仅需一个上述的construct可变参数模板,也可以满足很多情况的使用: ~~~ ... int main(){ mstl::allocator a;/《?》 A* p1=a.allocate(10); a.construct(p1,10);//int move constructor a.construct(p1,10,1.0);//int and double constructor int n1=10; double n2=2.0; a.construct(p1,n1,n2);//int and double constructor a.deallocate(p1,10); return 0; } 执行结果如下: int move constructor int and double constructor int and double constructor ~~~ --- MyTinySTL/allocator.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/MyTinySTL/allocator.h b/MyTinySTL/allocator.h index a3a5d4e..898eb9a 100644 --- a/MyTinySTL/allocator.h +++ b/MyTinySTL/allocator.h @@ -89,11 +89,17 @@ template mystl::construct(ptr, mystl::move(value)); } -template -template - void allocator::construct(T* ptr, Args&& ...args) -{ - mystl::construct(ptr, mystl::forward(args)...); +// template +// template +// void allocator::construct(T* ptr, Args&& ...args) +// { +// mystl::construct(ptr, mystl::forward(args)...); +// } + +template +template +void allocator::construct(Other* p,Args && ... args){ + ::new ((void*)p) Other(mstl::forward(args)...); } template