conversion ctors question

G

Grey Alien

I am baffled by this behaviour.

I have a class A declared as follows:

class A
{
public:
A();
explicit A(const std::string& value);
explicit A(const TimestampParam& value) ;
explicit A(const long value) ;
explicit A(const double value) ;
explicit A(const bool value) ;
A(const Object& value) ;
A(const A);
A& operator= (const A&);
~A();
}


I am using the class in statements like this:

std::vector<A> params ;

//field id
A field(100L) ; //requires 'L' specifier else ambigious ctor
params.push_back(field);

//field name
field = A(std::string("Homer")); //ok
params.push_back(field);


!!! PRETZEL LOGIC ALERT !!!

//field descr
field = A("likes donuts"); //calls A::A(const bool)
params.push_back(field);


Why is the compiler casting a std::string to bool? I took of the
explicit keyword so I could automatically convert between the supported
types and A, and still, std::string is being cast as bool - WHY ??? -
and how do I fix this?
 
G

Grey Alien

Grey said:
I am baffled by this behaviour.

I have a class A declared as follows:

class A
{
public:
A();
explicit A(const std::string& value);
explicit A(const TimestampParam& value) ;
explicit A(const long value) ;
explicit A(const double value) ;
explicit A(const bool value) ;
A(const Object& value) ;
A(const A);

correction:
A(const A&);
 
V

Victor Bazarov

Grey said:
I am baffled by this behaviour.

I have a class A declared as follows:

class A
{
public:
A();
explicit A(const std::string& value);
explicit A(const TimestampParam& value) ;
explicit A(const long value) ;
explicit A(const double value) ;
explicit A(const bool value) ;
A(const Object& value) ;
A(const A);
A& operator= (const A&);
~A();
}


I am using the class in statements like this:

std::vector<A> params ;

//field id
A field(100L) ; //requires 'L' specifier else ambigious ctor
params.push_back(field);

//field name
field = A(std::string("Homer")); //ok
params.push_back(field);


!!! PRETZEL LOGIC ALERT !!!

//field descr
field = A("likes donuts"); //calls A::A(const bool)
params.push_back(field);


Why is the compiler casting a std::string to bool?

Where do you see a string? Why do you think it's casting it to 'bool'?
I took of the
explicit keyword so I could automatically convert between the
supported types and A, and still, std::string is being cast as bool -
WHY ??? - and how do I fix this?

I don't see any std::string cast to bool. Please elaborate.

V
 
J

Jim Langston

Grey Alien said:
I am baffled by this behaviour.

I have a class A declared as follows:

class A
{
public: A();
explicit A(const std::string& value);
explicit A(const TimestampParam& value) ;
explicit A(const long value) ;
explicit A(const double value) ;
explicit A(const bool value) ;
A(const Object& value) ;
A(const A);
A& operator= (const A&);
~A();
}


I am using the class in statements like this:

std::vector<A> params ;

//field id
A field(100L) ; //requires 'L' specifier else ambigious ctor
params.push_back(field);

//field name
field = A(std::string("Homer")); //ok
params.push_back(field);


!!! PRETZEL LOGIC ALERT !!!

//field descr
field = A("likes donuts"); //calls A::A(const bool)
params.push_back(field);


Why is the compiler casting a std::string to bool?

"likes donuts" is not a std::string. It is a char array constant, a char
pointer if you will. You have no constructore that takes a char* as a
parameter. It seems the compiler finds bool as the one to use. If you want
a char* to be used as a constructor, then make one.
 
G

Giacomo Cerrai

Jim said:
explicit A(const bool value) ;

"likes donuts" is not a std::string.  It is a char array constant, a char
pointer if you will.  You have no constructore that takes a char* as a
parameter.  It seems the compiler finds bool as the one to use.  If you
want a char* to be used as a constructor, then make one.

shouldn't the 'explicit' keyword rule out this conversion?
that's what it's meant for, right?

g.
 
V

Victor Bazarov

Giacomo said:
shouldn't the 'explicit' keyword rule out this conversion?
that's what it's meant for, right?

'explicit' only concerns the conversion from the type of the argument
of your constructor into your type. You cannot control the language
standard conversions that way. The implicit conversion between
a pointer to an object and bool exists and cannot be removed.

V
 
J

James Kanze

[...]
"likes donuts" is not a std::string. It is a char array
constant, a char pointer if you will. You have no
constructore that takes a char* as a parameter. It seems the
compiler finds bool as the one to use. If you want a char* to
be used as a constructor, then make one.

You mean a char const* constructor, don't you?

The compiler is required to follow the rules of the language.
The language says that there is an implicit conversion of char
const* to bool, that the conversion of char const* to
std::string is a user defined conversion, and that implicit
conversions are to be prefered over user defined conversions.

My understanding is that the intent was that compilers would
warn about such implicit conversions; that they were present
simply to avoid breaking existing code. I don't know of any
compiler which does, however.

In the meantime, it's worth repeating a simple rule concerning
overloading: anytime you overload a function, make sure that
there is an overload for the type a constant value will
typically have. If you overload for any numeric type, for
example, ensure that you also overload for int. (Note that
A(42) will be ambiguous with the original code.) If you
overload for any floating point type, ensure that you also
overload for double. (If you only overload for int and float,
A(1.3) would be ambiguous.) And if you overload for std::string
(or any other class which would typically convert automatically
from a string literal), ensure that you also overload for char
const*. Note too in this respect that bool is an integral (and
thus a numeric) type.

If you're coding guidelines doesn't have a rule along these
lines, add it now.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,275
Latest member
Michaelachoda

Latest Threads

Top