Jump to content
  • Advertisement
Sign in to follow this  
n3Xus

[C++] Problems with overloaded funtion -std::string/ bool/double

This topic is 2909 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

I have a constructor that is overloaded, it can recieve a std::string, bool or a double:

MyCtor(const std::string& v)
MyCtor(double v)
MyCtor(bool v)

If I write MyCtor("bla") it calls the bool version, since char strings evaluate to true, MyCtor(std::string("bla")) fixes the problem.

If I call MyCtor(4), it calls bool since I'd have to write 4.0 to call the double ctor.

Is there a way to prevent this mess?

Share this post


Link to post
Share on other sites
Advertisement
If the type of the passed parameter does not match any of the overloaded constructors the compiler tries to find the best possible match.

If this match is not what you want, you have to convert the parameter to the right type.

MyCtor((double) 4);
MyCtor((std::string) "my string"); // or MyCtor(std::string("my string"));

If you want to be able to use MyCtor("my string") you have to define a MyCtor(const char*) or delete other constructors that have precedence for the type const char*.

What I don't know is how the compiler determines which overloaded constructor has precedence. (why does C("test") call C::C(bool) and not C::C(std::string)?) So if somebody knows the answer, I'm interested to know this. Is this in the C++ standard?

Why do you need multiple constructors with different types? Maybe you should use templates or specific methods.

Regards
aeroz

Edit:
With the g++ compiler MyCtor("bla") calls the bool version like you said, but MyCtor(4) gives me "error: call of overloaded 'MyCtor(int)' is ambiguous".

Share this post


Link to post
Share on other sites
Hey,

I'll try out templates, never used them much so they're not one of the things that come to my mind right away. Gotta try to incorporate them into my "problem solving toolset" now :P

Thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by aeroz
What I don't know is how the compiler determines which overloaded constructor has precedence. (why does C("test") call C::C(bool) and not C::C(std::string)?) So if somebody knows the answer, I'm interested to know this. Is this in the C++ standard?


I'd imagine that because const char* to bool is an integral conversion and const char * to std::string requires calling std::string's constructor to create a temporary object, the integral conversion wins without the compiler considering it ambiguous. Sure a standards expert here can confirm this.

I'd agree that a MyCtor(const char*) constructor is the way to go here, although I'm curious to know what this object is that requires these different constructors. If it is some kind of boost::any style object, template constructors are probably the way forward.

Share this post


Link to post
Share on other sites
The compiler doesn't magically know that an array of chars goes into std::string. The compiler sees std::string just like a custom string class you could make, or CString from the MFC libraries. You have to define a constructor like:


MyCtor(const char* v)
{
MyCtor(std::string(v));
}


to tell it how to deal with an array of characters (which is what "bla" is).

Share this post


Link to post
Share on other sites
nr: the explicit constructors fix the problems for bool and double, but for std::string it always uses bool ctor, so I changed it to const char* and it works now :D

Aardvajk: what do you mean by template ctor?

Share this post


Link to post
Share on other sites
Quote:
Original post by n3Xus
Aardvajk: what do you mean by template ctor?


I'm guessing wildly here, but let's say you want a class that can support a range of different types, for example to store variables in a scripting language implementation.

Proviso is that supported types have std::ostream << and std::istream >> operations supported.


class any
{
private:
std::stringstream s;

public:
template<class T> any(const T &t){ s << t; }

template<class T> T as() const
{
T t; s >> t;
if(s.fail()) throw conversion_error();
return t;
}
};

void f()
{
any a(23);
any b(23.0f);

int i=a.as<int>();
float f=b.as<float>();
}


Obviously may be barking entirely up wrong tree. Just seemed likely based on your list of required constructors.

Share this post


Link to post
Share on other sites
Aardvajk, I actually need the exact same thing you posted XD, I'm using this for Lua script, I may change my implmentation to what you showed me, thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by Blobberson
The compiler doesn't magically know that an array of chars goes into std::string. The compiler sees std::string just like a custom string class you could make, or CString from the MFC libraries. You have to define a constructor like:


MyCtor(const char* v)
{
MyCtor(std::string(v));
}


to tell it how to deal with an array of characters (which is what "bla" is).

As far as I know, calling other constructor inside a constructor does not work in C++. The code above creates a temporary object and does nothing with it.

Share this post


Link to post
Share on other sites
Quote:
Original post by aeroz
Quote:
Original post by Blobberson
The compiler doesn't magically know that an array of chars goes into std::string. The compiler sees std::string just like a custom string class you could make, or CString from the MFC libraries. You have to define a constructor like:


MyCtor(const char* v)
{
MyCtor(std::string(v));
}


to tell it how to deal with an array of characters (which is what "bla" is).

As far as I know, calling other constructor inside a constructor does not work in C++. The code above creates a temporary object and does nothing with it.

Correct. (While we can use initializer lists to specify which *inherited* class constructor to use, that's a different ballgame entirely.)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!