This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]