Overloaded constructor Problem

Started by
8 comments, last by klabautermann 15 years, 5 months ago
Hi there! For a university project im currently writing an engine, with a little help from the enginuity-tut and the GPG series. So far its working out pretty good, but im experiencing a problem with my Dators (a class that allows me to convert primitive types into strings and back). The Template constructors looks like that: TDator(std::string s) : str(s){} TDator(T value) : val(value){} with (as you can guess by now) members str and val. Worked just fine until i created a bool dator: TDator<bool> asd("0"); -> the compiler thinks the string parameter is an EXPRESSION and calls the SECOND constructor with 'true'. o.O Is there any way to avoid that unexpected behaviour? I COULD pack both constructors in one, but i think the problem is basic enough to be solved... Thanks for your help! Johannes
Advertisement
Explicit?
Construct (Free open-source game creator)
Quote:Original post by klabautermann
TDator<bool> asd("0");
-> the compiler thinks the string parameter is an EXPRESSION and calls the SECOND constructor with 'true'. o.O

Just as a technical note, the constructor chooses the implcit conversion from pointer-to-char to boolean over the two-step constructor making a std::string from the pointer-to-char. Basic function overload resolution rules. There is no string argument involved.

Stephen M. Webb
Professional Free Software Developer

Quote:Original post by AshleysBrain
Explicit?


thanks for the quick reply, but it didn't work, which accords to the article you linked with it... :(
i also get a c4800 warning, which basicly sais the same:
'type' : forcing value to bool 'true' or 'false' (performance warning)

@Bregma:
is there any way to supress these implicit conversions? the explicit keyword didn't do it.
I changed the constructor argument from std::string to const *char, but the compiler still chooses to take the bool constructor over the other one o.O
Technically those are not constructors yet conversion operators, can you post a working example of your problem please. I suspect you have defined a string conversion operator as well.
Quote:Original post by klabautermann
is there any way to supress these implicit conversions? the explicit keyword didn't do it.
I changed the constructor argument from std::string to const *char, but the compiler still chooses to take the bool constructor over the other one o.O

There is no way, other than making a constructor explicit, to suppress implicit conversions. Which constructor did you make explicit? It should be the constructor taking T, not the constructor taking std::string.

Stephen M. Webb
Professional Free Software Developer

Quote:Original post by klabautermann
i also get a c4800 warning, which basicly sais the same:
'type' : forcing value to bool 'true' or 'false' (performance warning)


This is because casting a pointer or number type to bool requires comparing if it is equal to 0 (because anything nonzero is 'true' or 1). Since this requires a comparison, performance will depend on branch prediction which, sometimes, is significant - but usually it's nothing to worry about, just a side-effect of the code you've written.

Eg. myBool = myInt; will give C4800, but if you do myBool = (myInt!=0); it won't bother you (!= returns a bool). Or just disable C4800.
Construct (Free open-source game creator)
Quote:Original post by klabautermann
Hi there!
For a university project im currently writing an engine, with a little help from the enginuity-tut and the GPG series. So far its working out pretty good, but im experiencing a problem with my Dators (a class that allows me to convert primitive types into strings and back).


Wouldn't a pair of template functions be better? T->string, string->T. Or even a single cast-style function such as boost::lexical_cast.
I don't see how the explicit keyword would help, the compiler is given a const char*, it has a choice of a function taking a std::string, or one where it can decide the type to use. The compiler will chose the path that requires least effort, which would be not constructing a std::string from a const char* to pass to the function.

You could use template specialisation to specialise a const char* version of the constructor, and behave like the first version of the constructor - I think anyway, I'm a bit hazy with template specialisations...
EDIT: Never mind, I can't read...
Sooo i just got back from university.
I've been a bit overhasty before. The reason changing the argument to a char pointer didn't work was simply because i didn't rebuild the entire programm before running it -.-
sry, stupid mistake.
Now everything works out just fine, the problem was in fact the implicit conversion-priority regarding std::string, AND the missing explicit (wow, both things I've never encountered), so thanks very much for the help there!

@the_edd:
I've equipped the dator with both, member conversion functions AND two static functions for fast use, works great for me and that way I can keep it all in the Dator-class, without having to define namespaces or global functions...

This topic is closed to new replies.

Advertisement