Prev: _CrtIsValidHeapPointer Assertion in C++/CLI Application Debug mode.
Next: Error LNK2028 unresolved token / LNK2019 Unrevolved external symbol
From: Ulrich Eckhardt on 10 Aug 2007 02:59 Gerry Hickman wrote: > Doug Harrison offered this example: > > ----- example start ----- > > I would use pass-by-reference to avoid this needless cost, e.g. > > vector<string>::size_type > void GetDeviceClasses(vector<string>& guids) > { [...] > returns guids.size(); > } Funny. Talking about needless costs and then returning redundant data - the size can be retrieved from the vector. Anyway, why would you write anything but clear code unless you first determined that it's a bottleneck? Just return the vector by value. > but when I came to actually code this, I ran into some problems. This doesn't help. What problems? > void PopulateStrings(vector<string> * guids) > { > guids->clear(); > guids->push_back("test1"); > guids->push_back("test2"); > } While this code will work, there is one thing I object to: in C++, where you have references, a pointer[1] means to me that something is optional, i.e. passing zero is okay, but you don't mean that. Still, you must handle that case, so either you just return (making it a non-error), throw an exception (making it a runtime error) or use assert() (making it a programmer's error). Not checking it is bad practice and will get you larted if you happen to be on my team. Uli [1] The exception is when an array/string is passed.
From: Gerry Hickman on 10 Aug 2007 10:34 Hi, Thanks to everyone who replied, I think I was confusing C with C++ style earlier. I found this article: <http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/cplr233.htm> that appears to explain both cases. Charles Wang[MSFT] wrote: > Hi Gerry, > Could you please let us know what the problems you ran into if you used > Doug's suggestion? > > It should also work if you use reference as following: > =================================== > vector<string> guids; > PopulateStrings(guids); > cout << "Count of guids is now " << guids.size(); // prints 2 > > void PopulateStrings(vector<string> & guids) > { > guids.clear(); > guids.push_back("test1"); > guids.push_back("test2"); > } > ================================== > > Best regards, > Charles Wang > Microsoft Online Community Support > ===================================================== > When responding to posts, please "Reply to Group" via > your newsreader so that others may learn and benefit > from this issue. > ====================================================== > This posting is provided "AS IS" with no warranties, and confers no rights. > ====================================================== > > > -- Gerry Hickman (London UK)
From: Doug Harrison [MVP] on 10 Aug 2007 16:04 On Fri, 10 Aug 2007 08:59:05 +0200, Ulrich Eckhardt <eckhardt(a)satorlaser.com> wrote: >Gerry Hickman wrote: >> Doug Harrison offered this example: >> >> ----- example start ----- >> >> I would use pass-by-reference to avoid this needless cost, e.g. >> >> vector<string>::size_type >> void GetDeviceClasses(vector<string>& guids) >> { >[...] >> returns guids.size(); >> } > >Funny. Talking about needless costs and then returning redundant data - the >size can be retrieved from the vector. What's "funny" is to compare returning a vector<string> by value to returning its size, the latter being as close to a free operation as there is, both in terms of complexity and exception safety. Not to mention, returning the size is a useful thing to do. >Anyway, why would you write anything >but clear code unless you first determined that it's a bottleneck? Just >return the vector by value. I don't know what's "funnier"; suggesting the code I presented isn't "clear", recommending returning a vector<string> by value, or equating returning a vector<string> by value with returning size(). You could almost take it on the road, I think. :) -- Doug Harrison Visual C++ MVP
From: Bo Persson on 10 Aug 2007 16:47 Doug Harrison [MVP] wrote: :: On Fri, 10 Aug 2007 08:59:05 +0200, Ulrich Eckhardt :: <eckhardt(a)satorlaser.com> wrote: :: ::: Gerry Hickman wrote: :::: Doug Harrison offered this example: :::: :::: ----- example start ----- :::: :::: I would use pass-by-reference to avoid this needless cost, e.g. :::: :::: vector<string>::size_type :::: void GetDeviceClasses(vector<string>& guids) :::: { ::: [...] :::: returns guids.size(); :::: } ::: ::: Funny. Talking about needless costs and then returning redundant ::: data - the size can be retrieved from the vector. :: :: What's "funny" is to compare returning a vector<string> by value to :: returning its size, the latter being as close to a free operation :: as there is, both in terms of complexity and exception safety. Not :: to mention, returning the size is a useful thing to do. How do you know that it is useful? Always? Assuming that we are trying to optimize a time-critical piece of code, why return a value that isn't asked for? Especially as it is also returned as a part of the guids parameter. It is also often not considered good style to have both a return value and out-parameters. If you need to, you can have several out-parameters, and not single out one of them as a return value. Bo Persson
From: Doug Harrison [MVP] on 10 Aug 2007 17:32
On Fri, 10 Aug 2007 22:47:34 +0200, "Bo Persson" <bop(a)gmb.dk> wrote: >Doug Harrison [MVP] wrote: >:: On Fri, 10 Aug 2007 08:59:05 +0200, Ulrich Eckhardt >:: <eckhardt(a)satorlaser.com> wrote: >:: >::: Gerry Hickman wrote: >:::: Doug Harrison offered this example: >:::: >:::: ----- example start ----- >:::: >:::: I would use pass-by-reference to avoid this needless cost, e.g. >:::: >:::: vector<string>::size_type >:::: void GetDeviceClasses(vector<string>& guids) >:::: { >::: [...] >:::: returns guids.size(); >:::: } >::: >::: Funny. Talking about needless costs and then returning redundant >::: data - the size can be retrieved from the vector. >:: >:: What's "funny" is to compare returning a vector<string> by value to >:: returning its size, the latter being as close to a free operation >:: as there is, both in terms of complexity and exception safety. Not >:: to mention, returning the size is a useful thing to do. > >How do you know that it is useful? Always? Often, after using a function with a name such as "GetDeviceClasses", a programmer wants to know how many such classes were found; he may be interested in the exact number, or he may just treat it as a boolean. Provided one can indicate errors in some other way, there's no reason not to return the number of items that were found, elements read, etc. >Assuming that we are trying to optimize a time-critical piece of code, >why return a value that isn't asked for? Especially as it is also >returned as a part of the guids parameter. The code in question populates a vector<string>, and judging by its name, probably enumerates the registry. I don't understand how anyone could worry about the efficiency of returning vector::size() in this context. (Granted, if you were talking about std::list, you might have a very, very tiny point, but to date, I'm unaware of anyone making vector::size worse than O(1).) >It is also often not considered good style to have both a return value >and out-parameters. This is not an example of bad style. (Q: What do you think this interface is equivalent to, if anything? To help you focus, you can limit yourself to standard functions.) >If you need to, you can have several >out-parameters, and not single out one of them as a return value. Yes, you can do that if you need to. -- Doug Harrison Visual C++ MVP |