This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
zero and pointer conversions in g++
- From: Thomas Braxton <brax108 at cox dot net>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 26 Dec 2005 14:04:52 -0600
- Subject: zero and pointer conversions in g++
I have this test code that I think g++ is selecting the wrong function when
the second argument is a zero. If compiled with HAVE_ASCII_DEFAULT 1 it
selects read(const char*, const char*) instead of read(const char*, const
Variant&), for test2a/test3a. If compiled with HAVE_ASCII_DEFAULT 0
compilation fails because test2a/test3a are ambiguous. Shouldn't all of the
tests select the Variant function, or am I missing something? Why do I have
to explicitly create a Variant when the argument is zero?
Tested w/ g++ 3.4.3 (Mandrakelinux 10.2 3.4.3-7mdk) and 4.0.1 (self compiled)
TIA,
Thomas
PS please CC as I'm not subscribed
#include <iostream>
#include <string>
#define HAVE_ASCII_DEFAULT 1
using std::string;
using std::ostream;
using std::cout;
using std::endl;
class Variant
{
public:
enum Type {
Invalid, Bool, Int, String
};
Variant() : i(), b(), s(), type(Invalid) { ; }
Variant(Type t) : i(), b(), s(), type(t) { ; }
Variant(bool b) : i(), b(b), s(), type(Bool) { ; }
Variant(int i) : i(i), b(), s(), type(Int) { ; }
Variant(const string& s) : i(), b(), s(s), type(String) { ; }
const char* type_name() const;
friend ostream& operator<<(ostream& os, const Variant& v);
private:
int i;
int b;
string s;
Type type;
};
const char* Variant::type_name() const
{
switch(type) {
case Bool: return "Bool";
case Int: return "Int";
case String: return "String";
default: break;
}
return "Invalid";
}
ostream& operator<<(ostream& os, const Variant& v)
{
os << "Variant(" << v.type_name();
switch(v.type) {
case Variant::Bool:
os << ", " << (v.b? "true": "false");
break;
case Variant::Int:
os << ", " << v.i;
break;
case Variant::String:
os << ", \"" << v.s.c_str() << '\"';
break;
default:
break;
}
return os << ')';
}
class Config
{
public:
Config() { ; }
string read(const char* pKey, const string& aDefault) const;
#if HAVE_ASCII_DEFAULT
string read(const char* pKey, const char* aDefault) const;
#endif
Variant read(const char* pKey, const Variant& aDefault) const;
};
#if HAVE_ASCII_DEFAULT
string Config::read( const char *pKey, const char *aDefault ) const
{
if (!aDefault)
return read(pKey, string());
return read(pKey, string(aDefault));
}
#endif
string Config::read( const char *pKey, const string& aDefault ) const
{
cout << __PRETTY_FUNCTION__ << '\t' << (pKey && *pKey? pKey: "null") << endl
<< "\taDefault = \"" << aDefault.c_str() << '"' << endl;
return aDefault;
}
Variant Config::read( const char *pKey, const Variant &aDefault ) const
{
cout << __PRETTY_FUNCTION__ << '\t' << (pKey && *pKey? pKey: "null") << endl
<< "\taDefault = " << aDefault << endl;
return aDefault;
}
int main(int, char**)
{
Config config;
// bool
config.read("test1", true);
config.read("test2a", false);
config.read("test2b", Variant(false));
config.read("test3a", bool());
config.read("test3b", Variant(bool()));
return 0;
}