Tải bản đầy đủ - 0 (trang)
Chapter 58.  Keep types and functions in separate namespaces unless they're specifically intended to work together

Chapter 58.  Keep types and functions in separate namespaces unless they're specifically intended to work together

Tải bản đầy đủ - 0trang

Summary

Helppreventnamelookupaccidents:Isolatetypesfrom

unintentionalargument-dependentlookup(ADL,alsoknownas

Koeniglookup),andencourageintentionalADL,byputtingthem

intheirownnamespaces(alongwiththeirdirectlyrelated

nonmemberfunctions;seeItem57).Avoidputtingatypeinto

thesamenamespaceasatemplatedfunctionoroperator.



Discussion

Byfollowingthisadvice,youwillavoidhavingtotrackdown

hard-to-diagnoseerrorsinyourcodeandavoidhavingtoknow

aboutexcessivelysubtlelanguagedetailsthatyou,well,should

neverhavetoknowabout.

Considerthisactualexamplethatwaspostedpubliclytoa

newsgroup:

#include

namespaceN{

structX{};

template

int*operator+(T,unsigned){/*dosomething*/}

}

intmain(){

std::vectorv(5);

v[0];

}



Thestatementv[0];compilesonsomestandardlibrary

implementationsbutnotonothers.Tomakeaverylongstory

moderatelylesslong(takeadeepbreath):Theexceedingly

subtleproblemisthatinsidemostimplementationsof

vector::operator[]lurkscodelikev.begin()+n,and

thenamelookupforthatoperator+functionmightreachout

intothenamespace(hereN)ofthetypethatvectoris

instantiatedwith(hereX).WhetheritreachesoutintoNlike

thatdependsonhowvector::iteratorhappenstobe



definedinthatreleaseofthatstandardlibrary

implementationbutifitdoeslookintoN,thenitwillfind

N::operator+.Finally,dependingonthetypesinvolved,the

compilermightjustdiscoverthatN::operator+isabetter

matchthanthestd::operator+forvector::iterators

thatwasprovided(andintendedtobecalled)inthatstandard

libraryimplementation.(Onewaythatthestandardlibrary

implementationcouldprotectitselffromthisistonotwritecode

likev.begin()+ninthatway,whichinjectsanunintentional

pointofcustomization:Eitherarrangeforv.begin()'stypeto

notdependinanywayonthetemplateparameter,orrewrite

thecalltooperator+asaqualifiedcall.SeeItem65)

Inshort,you'llalmostcertainlyneverfigureoutwhat'sgoingon

fromtheerrormessageifyou'reluckyenoughtogetanerror

message,thatis,becauseyoumighthappentohittheworstof

allpossibleworldswhereN::operator+ischosenbut

unfortunatelyturnsouttobecompilable,althoughcompletely

unintendedandwildlywrong.

Ifyouthinkyouhaven'tbeenbitbythis,justthinkback:Can

yourememberatimewhenyouwrotecodethatusedthe

standardlibrary(forexample)andgotmysteriousand

incomprehensiblecompilererrors?Andyoukeptslightly

rearrangingyourcodeandrecompiling,andrearrangingsome

moreandcompilingsomemore,untilthemysteriouscompile

errorswentaway,andthenyouhappilycontinuedonwithat

bestafaintnaggingcuriosityaboutwhythecompilerdidn'tlike

theonly-ever-so-slightlydifferentarrangementofthecodeyou

wroteatfirst?We'veallhadthosedays,andtheoddsare

decentthatthemysteryculpritwassomeformofthe

aforementionedproblem,whereADLpulledinnamesfrom

othernamespacesinappropriatelyjustbecausetypesfrom

thosenamespaceswerebeingusednearby.

Thisproblemisnotuniquetousesofthestandardlibrary.It

cananddoeshappeninC++withtheuseofanytypethatis



definedinthesamenamespaceasfunctionsespecially

templatedfunctions,andmostespeciallyoperatorsthataren't

specificallyrelatedtothattype.Don'tdothat.

Bottomline:Youshouldn'thavetoknowthisstuff.Theeasiest

waytoavoidthiswholecategoryofproblemsistoingeneral

avoidputtingnonmemberfunctionsthatarenotpartofthe

interfaceofatypeXintothesamenamespaceasX,and

especiallynevereverputtemplatedfunctionsoroperatorsinto

thesamenamespaceasauser-definedtype.

Note:Yes,theC++standardlibraryputsalgorithmsandother

functiontemplates,suchascopyanddistance,intothesame

namespaceaslotsoftypes,suchaspairandvector.Itputs

everythingintoasinglenamespace.That'sunfortunate,andit

causesexactlythesekindsofverysubtleproblems.Weknow

betternow.Learnfromthepast.Don'tdothat.

Fortheflipsideofthisissue,seeItem57.



References

[Stroustrup00]Đ10.3.2,Đ11.2.4[Sutter00]Đ34[Sutter02]

Đ39-40



59.Don'twritenamespaceusingsina

headerfileorbeforean#include

Summary

Discussion

Exceptions

References



Summary

Namespaceusingsareforyourconvenience,notforyouto

inflictonothers:Neverwriteausingdeclarationorausing

directivebeforean#includedirective.

Corollary:Inheaderfiles,don'twritenamespace-levelusing

directivesorusingdeclarations;instead,explicitlynamespacequalifyallnames.(Thesecondrulefollowsfromthefirst,

becauseheaderscanneverknowwhatotherheader#includes

mightappearafterthem.)



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 58.  Keep types and functions in separate namespaces unless they're specifically intended to work together

Tải bản đầy đủ ngay(0 tr)

×