|
Boost : |
From: Andrea Torsello (torsello_at_[hidden])
Date: 2004-04-15 13:34:19
Hi, I have been investigating move semantics and think that I came up with a
solution that is strongly influenced by both David Abrahams' move approach
and Andrei Alexandrescu's mojo, but solves some of the problems I have
encountered with them.
The basic idea is to use the explicit keyword to force the compiler to use
the X(X const &) constructor only in two cases.
1) When explicitly copying a const object i.e.
X const x;
X y(x); //use explicit copy constructor
2) When passing by const ref
void f(X const &);
X makeX();
void foo()
{
f(makeX()); //use explicit copy constructor
}
In all other cases the other constructor take precedence.
Note that the template trick David Abrahams uses in his move approach would
lead to an error on a conforming compiler when confronted with case #2
(unless more recent versions corrected this).
I chose to keep the temporary and constant subtypes from mojo because they
allow me to discriminate between const values, non-const rvalues and
non-const rvalues.
The lack of this capability was the major problem I had with David Abrahams'
move.
My use-case was a vector-like container that increases but never decreases
the size of its backing store.
In order to provide the never decreasing backing-store semantic, operator =
moves the backing store from a temporary only if the new data does not fit
in the existing space.
Hence, operator = must be able to discriminate between temporaries and
non-temporaries.
My solution fullfills almost all the requirements I had:
1) passing by value moves non-const rvalues and copies everithing else.
2) its is transparent to the user of the class.
Alexandrescu's Mojo fails this because of the special return type, while
Abrahams' move fails it because of the pass-by-const-ref problem described
above.
3) it allows to discriminate between constants, non-const lvalues, and
non-const rvalues.
Alexandrescu's Mojo allows it, while Abrahams' move does not.
4) Provides move semantics to templated classes with (almost) no odd
side-effect.
The only side-effect is that template type deduction does not work with
temporary discrimination. Hence in the sample code the template type of the
"discriminate" function must be specified explicitly.
please find attached a sample file illustrating my move approach.
I tested the code with gcc 3.3.1 and successfully compiled it with comeau
online.
What do you think?
Andrea Torsello
P.S. please cc me as I am not subscribed and I check the mailinglist
archives sporadically
begin 666 move_test.cc
M(VEN8VQU9&4\:6]S=')E86T^#0H-"@T*=7-I;F<@<W1D.CIC;W5T.PT*=7-I
M;F<@<W1D.CIE;F1L.PT*#0IN86UE<W!A8V4@;6]V90T*>PT*"71E;7!L871E
M(#QC;&%S<R!4/B!S=')U8W0_at_96YA8FQE9 T*"7L-"@D)8VQA<W,@8V]N<W1A
M;G0@+R\@='EP92!S=6=A<B!F;W(@8V]N<W1A;G1S#0H)"7L-"@D)8V]N<W0@
M5"H_at_9&%T85\[#0H)"7!U8FQI8SH-"@D)97AP;&EC:70_at_8V]N<W1A;G0H8V]N
M<W0_at_5"8@;V)J*2 Z(&1A=&%?*"9O8FHI('M]#0H)"6-O;G-T(%0F(&=E="@I
M(&-O;G-T('L@<F5T=7)N("ID871A7SL@?0T*"0E].PT*#0H)"6-L87-S('1E
M;7!O<F%R>2 Z('!R:79A=&4_at_8V]N<W1A;G0@+R\@='EP92!S=6=A<B!F;W(@
M=&5M<&]R87)I97,-"@D)>PT*"0EP=6)L:6,Z#0H)"65X<&QI8VET('1E;7!O
M<F%R>2A4)B!O8FHI(#H_at_8V]N<W1A;G0H;V)J*2![?0T*"0E4)B!G970H*2!C
M;VYS="![(')E='5R;B!C;VYS=%]C87-T/%0F/BAC;VYS=&%N=#HZ9V5T*"DI
M.R!]#0H)"7T[#0H-"@EO<&5R871O<B!T96UP;W)A<GDH*0T*"7L-"@D@(" @
M<F5T=7)N('1E;7!O<F%R>2AS=&%T:6-?8V%S=#Q4)CXH*G1H:7,I*3L-"@E]
M#0H);W!E<F%T;W(@8V]N<W1A;G0H*2!C;VYS= T*"7L-"@D@(" @<F5T=7)N
M(&-O;G-T86YT*'-T871I8U]C87-T/&-O;G-T(%0F/B_at_J=&AI<RDI.PT*"7T-
M"@T*#0H)<')O=&5C=&5D._at_T*"0EE;F%B;&5D*"D@>WT@+R\@:6YT96YD960@
M=&\@8F4_at_9&5R:79E9"!F<F]M#0H)"7YE;F%B;&5D*"D@>WT@+R\@:6YT96YD
M960@=&\@8F4_at_9&5R:79E9"!F<F]M#0H)?3L-"GT-"@T*=&5M<&QA=&4\='EP
M96YA;64_at_5#X-"F-L87-S(%D_at_.B!P=6)L:6,@;6]V93HZ96YA8FQE9#Q9/%0^
M(#X-"GL-"G!U8FQI8SH-"G1Y<&5D968@='EP96YA;64@;6]V93HZ96YA8FQE
M9#Q9/%0^(#XZ.G1E;7!O<F%R>2!T96UP;W)A<GD[#0IT>7!E9&5F('1Y<&5N
M86UE(&UO=F4Z.F5N86)L960\63Q4/B ^.CIC;VYS=&%N="!C;VYS=&%N=#L-
M"@T*62_at_I('M]#0H-"F5X<&QI8VET(%DH63Q4/B!C;VYS=" F*2![(&-O=70@
M/#P@(F5X<&QI8VET(&-O<'D_at_8V]N<W1R=6-T;W)<;B([('T-"EDH63Q4/B8I
M('L_at_8V]U=" \/" B;F]N+6-O;G-T(&QV86QU92!C;W!Y(&-O;G1R=6-T;W)<
M;B([('T-"EDH8V]N<W1A;G0I('L_at_8V]U=" \/" B8V]N<W0_at_8V]P>2!C;VYS
M=')U8W1O<EQN(CL@?0T*62AT96UP;W)A<GDI('L_at_8V]U=#P\(")N;VXM8V]N
M<W0@<G9A;'5E(&UO=F4_at_8V]N<W1R=6-T;W)<;B([('T-"GT[#0H-"@T*=&5M
M<&QA=&4\='EP96YA;64_at_5#X-"ED\5#X@;6%K95DH*2![<F5T=7)N(%D\5#XH
M*3M]#0H-"G1E;7!L871E/'1Y<&5N86UE(%0^#0I9/%0^(&-O;G-T(&UA:V59
M8V]N<W0H*2![<F5T=7)N(%D\5#XH*3M]#0H-"@T*=&5M<&QA=&4\='EP96YA
M;64_at_5#X-"G9O:60_at_9V5T62A9/%0^*2![?0T*#0IT96UP;&%T93QT>7!E;F%M
M92!4/@T*=F]I9"!G9719<F5F*%D\5#XF*2![?0T*#0IT96UP;&%T93QT>7!E
M;F%M92!4/@T*=F]I9"!G97198V]N<W1?<F5F*%D\5#X_at_8V]N<W0@)BD@>WT-
M"@T*#0IT96UP;&%T93QT>7!E;F%M92!4/@T*=F]I9"!D:7-C<FEM:6YA=&4H
M63Q4/B8I('MC;W5T(#P\(")D:7-C<FEM:6YA=&4Z(&YO;BUC;VYS="!L=F%L
M=65<;B([?0T*#0IT96UP;&%T93QT>7!E;F%M92!4/@T*=F]I9"!D:7-C<FEM
M:6YA=&4H='EP96YA;64_at_63Q4/CHZ8V]N<W1A;G0I('MC;W5T(#P\(")D:7-C
M<FEM:6YA=&4Z(&-O;G-T('9A;'5E7&XB.WT-"@T*=&5M<&QA=&4\='EP96YA
M;64_at_5#X-"G9O:60_at_9&ES8W)I;6EN871E*'1Y<&5N86UE(%D\5#XZ.G1E;7!O
M<F%R>2D@>V-O=70@/#P@(F1I<V-R:6UI;F%T93H@;F]N+6-O;G-T(')V86QU
M95QN(CM]#0H-"FEN="!M86EN*"D-"GL-"ED\:6YT/B!Y,3L-"ED\:6YT/B!C
M;VYS="!Y,CL-"@T*63QI;G0^('0Q*'DQ*3L@+R]C;W!Y(&YO;BUC;VYS="!L
M=F%L=64-"ED\:6YT/B!T,BAY,BD[("\O8V]P>2!C;VYS="!L=F%L=64-"ED\
M:6YT/B!T,RAM86ME63QI;G0^*"DI.R O+V-O<'D@=&5M<&]R87)Y#0I9/&EN
M=#X@=#0H;6%K95EC;VYS=#QI;G0^*"DI.R O+V-O<'D_at_8V]N<W0@=&5M<&]R
M87)Y#0H-"F=E=%EC;VYS=%]R968H>3$I.R O+W!A<W,M8GDM8V]N<W0M<F5F
M(&YO;BUC;VYS="!L=F%L=64-"F=E=%EC;VYS=%]R968H>3(I.R O+W!A<W,M
M8GDM8V]N<W0M<F5F(&-O;G-T(&QV86QU90T*9V5T66-O;G-T7W)E9BAM86ME
M63QI;G0^*"DI.R O+W!A<W,M8GDM8V]N<W0M<F5F(&YO;BUC;VYS="!T96UP
M;W)A<GD-"F=E=%EC;VYS=%]R968H;6%K95EC;VYS=#QI;G0^*"DI.R\O<&%S
M<RUB>2UC;VYS="UR968_at_8V]N<W0@=&5M<&]R87)Y#0H-"F=E=%DH>3$I.R O
M+W!A<W,M8GDM=F%L=64@;F]N+6-O;G-T(&QV86QU90T*9V5T62AY,BD[("\O
M<&%S<RUB>2UV86QU92!C;VYS="!L=F%L=64-"F=E=%DH;6%K95D\:6YT/B_at_I
M*3L@+R]P87-S+6)Y+79A;'5E(&YO;BUC;VYS="!T96UP;W)A<GD-"F=E=%DH
M;6%K95EC;VYS=#QI;G0^*"DI.R O+W!A<W,M8GDM=F%L=64@;F]N+6-O;G-T
M('1E;7!O<F%R>0T*#0ID:7-C<FEM:6YA=&4\:6YT/BAY,2D[("\O;F]N+6-O
M;G-T(&QV86QU90T*9&ES8W)I;6EN871E/&EN=#XH>3(I.R O+V-O;G-T(&QV
M86QU90T*9&ES8W)I;6EN871E/&EN=#XH;6%K95D\:6YT/B_at_I*3L@+R]N;VXM
M8V]N<W0@=&5M<&]R87)Y#0ID:7-C<FEM:6YA=&4\:6YT/BAM86ME66-O;G-T
M/&EN=#XH*2D[("\O8V]N<W0@=&5M<&]R87)Y#0H-"@T*<F5T=7)N(# [#0I]
`
end
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk