Journal Articles
Browse in : |
All
> Journals
> CVu
> 145
(10)
All > Journal Columns > LettersEditor (132) Any of these categories - All of these categories |
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: Letters to the Editor
Author: Administrator
Date: 08 October 2002 13:15:55 +01:00 or Tue, 08 October 2002 13:15:55 +01:00
Summary:
Body:
Under the title "this->evolve()", James wrote about the scope of C Vu. I don't agree that C Vu shall be a magazine for Python or Java users. Firstly, if this happens, I would feel left out as a Perl user. No, C Vu cannot cover every language. Secondly, I don't think the world needs another forum for Python/Java/... If I want to get in depth with Python or Java, then I would turn to existing forums where there is enough depth and big audiences.
However I think it would be interesting for C Vu to include articles on other languages with a C/C++ slant, such as how to use C/C++ libraries from Python/Java and comparisons of languages in various aspects. Yes I expect a few articles would favour C++ over Java just as a Java magazine would favour Java but I don't see any problems with this.
Sorry for complaining when I am not contributing to C Vu. However I do enjoy reading C Vu even if there are non-C/C++ features like "Professionalism in Programming" and "A Short History of Character Sets".
Best regards
Sven Rosvall
<Sven_Rosvall@programmingresearch.ie>
Thank you for taking the time to express an opinion. I certainly don't see C Vu as being a magazine for Python or Java users, but I do see that carrying a small amount of content for languages other than C and C++ is appropriate. I hope that the readership will make their opinions known and shape the form that C Vu takes in 2003. - James
Dear James,
I received the following collection of traps hidden in typos and misconceptions from David Caabeiro <<dac@globalmente.com>> (one of our newer members). They are exactly the kind of thing that I was looking for when I presented the original little puzzle in my column. I wonder if other readers can be stimulated by this to add a few more of their own.
class foo { public: static void f() {} }; void f() {} foo:f(); // this calls global f() switch(c){ case 0: return 0; case 1: return 1; defualt: return -; // default misspelled }; string s(); // This is a declaration, not a // construction with no args int main(){ int *v = new int(10); // instead of new int[10] for (int i = 0; i < 10; ++i) v[i] = i; } char names[] = { "David", "John", "Peter" // comma forgotten here! "Mary", "George" };
And finally the classic:
void foo() {} foo; // Forgot()
I hate to think how many hours I have wasted with variants of that last one. Of course good compilers at a sufficiently high level of warnings give a diagnostic warning for many of them. That alone should be a good reason to switch to high warning levels. Unfortunately that often generates spurious warnings from third party libraries resulting in us fiddling around with #pragmas to hide them.
Francis Glassborow
James,
1. The code can be shortened by replacing the definition of struct is_space with a call to ptr_fun(isspace) from the header <functional>
2. The version of isspace Paul uses does not come from <locale> but from the C-compatibility library <cctype> To use the <locale> version you must pass a locale object as a second argument. This can make the utility more flexible.
3. I think it's good practice to use const_iterator whenever you don't need an writable iterator. It's safer.
4. I get suspicious when I see things like the following:
str = (str_start < str_end) ? std::string(str_start, str_end) : "";
This checks for a "special case". Special cases are inelegant. Programs are meant to model the real world, but in my experience there are not as many special cases in the real world as programmers think there are. Is the above really a special case? I don't think so. The need for the test stems from scanning the whole string backwards. Since it has already been scanned forwards, and a starting position already found, we only need to scan backwards up to that position.
So we have:
void rem_space(std::string& str) { typedef std::string::const_iterator str_it; const str_it str_start = std::find_if(str.begin(), str.end(), std::not1(ptr_fun(isspace)); const str_it str_end = std::find_if(str.rbegin(), std::string::const_reverse_iterator( str_start), std::not1(ptr_fun(isspace)).base(); str = std::string(str_start, str_end); }
Personally, I would have preferred this function to return the result instead of changing the parameter:
const std::string trim(const std::string &);
Finally, it can be advantageous to templatize it so that it can work with wchar_t as well as char. I leave that as an exercise.
Klitos Kyriacou
Paul Whitehead has provided a response to the message from Klitos, which I reproduce below:
James,
I would like to reply, at least in brief, if only as a kind-of "thank you" for replying to the original article. Firstly I'd like to say thanks to Klitos Kyriacou for reading the article. Secondly, I'd like to say thanks for taking the time and effort to reply. It is appreciated.
Thirdly, I have an admission to make: I wrote the article/code in January this year (just after the heady days of Christmas/New Year celebrations :- ). Since then, I've been changing compilers and platforms so often and have also had a hard-disk failure (yes, _of course_ I backed-up the hard- drive regularly, just not the things it turned out I needed ;- that I have to confess I've "mislaid" the original code; the article too, as it happens, but then it's been reprinted in CVu so at least I can read my own article there! Now, I did send a copy of the code to be made available on the ACCU website but I haven't seen it on there in any recognisable form as yet, so I'll have to do some of this from memory - bear with me, if you can.
Points 1 and 4: yes, ptr_fun is good. Tidies things up a little. However, my own dissatisfaction with the solution I provided is that I find the whole thing just too verbose for what seems to be a rather trivial problem. Later on (point 4) you talk about a "special case" and say that it is inelegant. I would go further and say that special cases do not exist. They are simply a degenerate case of a more general rule - a general rule which just hasn't been found (or even looked for?) yet. When I do design reviews (and in general they tend to be OO and UML) I consistently weed out special cases as it shows, at least to my mind, that the problem is not correctly understood and therefore the solution is not correct. If this sounds a little extreme, then at least you can see that I fully support your point (4). I would, however, like to take the thought processes in your point (4) a lot further. As I have already mentioned, I find the whole thing too verbose and I suspect a more radical re-think of the initial solution - along the lines of your point (4), but more of it - may be required. Any takers amongst the C Vu readership?
Point 2 re: locale - yes, passing a locale to isspace does call up the locale version and this, as you rightly say, will make the utility more flexible.
Point 3 re: const_iterator - hmmm, well, yes, I do tend to use const_iterator whenever I can - and even "const container_type::const_iterator it = ..." where possible. I do this despite other people arguing convincingly that you may as well use the "simple" iterator in pretty much most cases. Scott Meyer's Effective STL springs to mind as having this guideline somewhere (but don't quote me, I need to check!). So using const_iterator is arguably not such a good thing as it may first appear. However, being stubbornly const correct (at least I hope I am!) I just can't bring myself to type "iterator" when "const_iterator" would work too.
Back to point (4) if I may. I'm not sure about passing back a const copy of the string object as it doesn't really get you much. A const ref, assuming, of course, it isn't a ref to a local (i.e. automatic) in the function or a const pointer (ditto) - that's fine. But a const copy? What are you going to do with it? If it is going to be used in another object then there's nothing stopping me doing this:
using std::string; string mySpaceStr(" abc def "); string myStr( trim(mySpaceStr) );
I could make mySpaceStr a const object and it still wouldn't change matters as myStr would still be non-const, as I wished - assuming I'm not just being sloppy and really did want a non-const myStr string object. Copy constructors (and assignment operators) in general take a const reference as their argument so by returning a const copy of the object from the trim function, all you are doing is passing that const object into a copy constructor in the above case) and then creating the non-const myStr object from it. A notable exception to the const argument for copy constructor/assignment operator is std::auto_ptr<> - and in that case it _may_ make sense to pass back a const auto_ptr<> as a return value, but that's a different story...
You mention making the function a template function. Yes, this would increase its flexibility somewhat. I would find the whole trim() function much tidier if it were to become a method on the std::basic_string<> class (thereby incurring the wrath of the multitude who believe basic_string<> has too many methods already!). If you consider the following, we could have:
1. trim(string&) - which modifies the argument, original proposal, or
2. string trim(const string&) - which doesn't modify the argument and returns a new string object (non-const, as per my comments above) as you suggest in your comments, or
3. method on the class. Sample usage: string mySpaceStr( " abc def "); mySpaceStr.trim(); After this operation, mySpaceStr now hopefully contains "abc def"
I find option 3 preferable.
Regards,
Paul Whitehead
Notes:
More fields may be available via dynamicdata ..