From: gast128 on
Dear all,

we just discovered a production code error:

class K
{
public:
explicit K(bool){}
//explicit K(boost::tribool){}
explicit K(const std::string&){}
};


int main()
{
//takes boolean constructor instead of std::string
K k("e");
return 0;
}

is there a simple c++ trick to invoke at class K an ambiguity when fed
with a const char* pointer? The one with the boost::tribool gives also
an ambiguity.

wkr,
me


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Vidar Hasfjord on
On Jun 20, 8:45 pm, "gast...(a)hotmail.com" <gast...(a)hotmail.com> wrote:
> [...]
> explicit K(bool){}
> explicit K(const std::string&){}
> [...]
> is there a simple c++ trick to invoke at class K an ambiguity when fed
> with a const char* pointer?

It seems that the better course of action here is to force the
intended intuitive constructor selection; not cause an ambiguity.

You can do that by adding a constructor taking const char* and/or
replace the problematic bool-converting constructor with a less
promiscuous alternative, such as a constructor taking an enum type
parameter, e.g. enum Option {Yes, No}.

If you really want an ambiguity in this case you can replace the bool
parameter with a wrapper:

struct Boolean {
bool v;
Boolean (bool v_) : v (v_) {}
operator bool () {return v;}
};

Regards,
Vidar Hasfjord


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Chris Uzdavinis on
On Jun 20, 3:45 pm, "gast...(a)hotmail.com" <gast...(a)hotmail.com> wrote:

> class K
> {
> public:
> explicit K(bool){}
> //explicit K(boost::tribool){}
> explicit K(const std::string&){}
>
> };
>
> int main()
> {
> //takes boolean constructor instead of std::string
> K k("e");
> return 0;
>
> }
>
> is there a simple c++ trick to invoke at class K an ambiguity when fed
> with a const char* pointer? The one with the boost::tribool gives also
> an ambiguity.

You can make the constructor taking char const * private:

class K
{
public:
explicit K(bool){}
explicit K(const std::string&){}
private:
K(char const *); // not implemented
};

But before you continue, it might be worth asking why the constructor
is overloaded on bool and string values in the first place. It does
seem a little bit strange. Is the class playing multiple roles?
Should it be two different classes? Etc.

--
Chris

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: gast128 on
> You can make the constructor taking char const * private:
This will help. Thx. Not sure if there are more 'unexpected'
conversions possible when adding more overloaded constructors to a
class.

> But before you continue, it might be worth asking why the constructor
> is overloaded on bool and string values in the first place. It does
> seem a little bit strange. Is the class playing multiple roles?
> Should it be two different classes? Etc.
No it's correct. Bool is to indicate to a create a new unique or empty
value, the string is for loading it with a previous value.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: gast128 on
> You can do that by adding a constructor taking const char*
This will help.

> replace the problematic bool-converting constructor with a less
> promiscuous alternative, such as a constructor taking an enum type
> parameter, e.g. enum Option {Yes, No}.
I had thought of the enumerate myself, but I find that disappointing
since the bool type is just intended for that.

>
> If you really want an ambiguity in this case you can replace the bool
> parameter with a wrapper:
>
> struct Boolean {
> bool v;
> Boolean (bool v_) : v (v_) {}
> operator bool () {return v;}
> };
This is the same solution as using the boost::tribool. You can not
write 'K k(false);' anymore, one must write than 'K
k(boost::tribool(false))';




--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]