Quote:Original post by Wolfdog
Quote:Original post by MaulingMonkey
I wouldn't say that if you weren't already aware of these conversion opportunities.
Ouch!
Meh. C++ is an insanely complex language -- and a dangerous-by-default one on top of that. My point is merely that you'd do well to have more prudence -- it's not so much the words that matter so much as the implications. Even I, one of the more knowledgeable people about the C++ language in this community, treat my knowledge of the language with guarded pessimism, for as much as I know about C++, I also know how much I
don't know about C++.
And with this dangerous language, knowing what you don't know is almost as important as knowing what you do know. Maybe even more important.
Compared to Koeing lookup, sequence points, template specialization, dependant typenames, pointer-to-members, the details of integral promotion, operator chaining, and goodness knows what other examples I've missed thinking of, this conversion stuff isn't exactly on the "advanced topics" list, a list I'd expect familiarity with from one with "a very good grasp" on the language.
Quote:I did not look deep enough into this, you have to use const if the object is to be passed by reference and this makes perfect sense because you would not want to pass the created object by reference. "A or const A&"
Right -- if you want non-const-reference access, you don't want implicit conversions hiding your variable changes by substituting a discarded temporary -- but it's otherwise sensible.
Quote:Quote:Original post by MaulingMonkey
Care to say why you feel that you should be forced to do this?
Sure, but I must warn first that this is my personal opinion and I may not have all the facts that the C++ Standards Committee may have had when they decided to add this.
Of course.
Quote:The reason I feel this way is as you said 'Explicitness'. Although in the case that std::string and const char * could potentially be both "Strings", const char * could also be an array of bytes that describe something entirely different. In the case that they are two obviously different types the code could be somewhat confusing:
*** Source Snippet Removed ***
If it's questionable enough for there to be ambiguity, chances are more than likely it's ambiguous to the compiler too -- which means it'll generate a compiler error:
struct foo { foo( int ) {} };struct bar { bar( int ) {} };void f( foo ) {}void f( bar ) {}void example() { f( 42 ); // MSVC2005 generates: // error C2668: 'f' : ambiguous call to overloaded function // could be 'void f(bar)' // or 'void f(foo)' f( foo(42) ); // OK f( bar(42) ); // OK}
While you will eventually run into some problems statements not doing what you think they do, most can be prevented with the use of
explicit and such. The remaining problems caused by implicit conversions -- if your code is done right at any rate -- are outweighed as a whole by the problems you avoid by being able to actually read your code (by allowing you to spot errors before they become problems, or to spot problems before they lead to an entire symphony of cascading problems.)
Quote:Ofcourse I have absolutly nothing against this type of argument transformation I am just taking a deep look at something new to me. Who knows maybe tomorrow I will decide it is very useful, I have only known about this for one day.
Hence my questioning -- whether it be to assuage misplaced fears or to explain the other half of the argument, or simply to chime in with what tools you have at your disposal for dealing with valid issues.