Tom
Tom

Reputation: 269

Function/Method Overloading C++: Data type confusion?

I'm having some trouble overloading methods in C++. As an example of the problem, I have a class with a number of methods being overloaded, and each method having one parameter with a different data type. My question: is there a particular order in the class these methods should appear in, to make sure the correct method is called depending on its parameters data type?

class SomeClass{
    public:
    ...
    void Method(bool paramater);
    void Method(std::string paramater);
    void Method(uint64_t paramater);
    void Method(int64_t paramater);
    void Method(uint8_t paramater);
    void Method(int8_t paramater);
    void Method(float paramater);
    void Method(double paramater);
    void Method(ClassXYZ paramater);
}

I noticed there was problem because when running:

Method("string");

it was calling:

Method(bool paramater);

Upvotes: 9

Views: 4235

Answers (7)

Sandeep
Sandeep

Reputation: 3277

You can add an explict keyword so as to take the intended argument.

Upvotes: 1

Tomas
Tomas

Reputation: 5143

The order is of no importance. The problem here is that when you invoke

Method("string");

you are passing a const char[]. This will be converted to bool implicitly. What you want to do is pass an std::string explicitly:

Method( std::string("string"));

Upvotes: 4

Antonio Pérez
Antonio Pérez

Reputation: 6982

Not answering your question but, just out of curiosity, is there a hidden reason for not using a template method instead of defining an overload version for each type?

class SomeClass
{
    public:
    ...
    template <typename T>
    void Method(T paramater);
};

Upvotes: 2

AnT stands with Russia
AnT stands with Russia

Reputation: 320551

The order makes no difference. The method to call is selected by analyzing the types of arguments and matching them to the types of parameters. In case there's no exact match, the best-matching method is selected. In your case it happens to be the bool method.

You are supplying an argument of type const char[7]. According to the C++ overloading rules, the best path here is to let const char[7] decay to const char * and then convert it to bool using a standard conversion. The path with converting to std::string is considered worse, since it would involve a user-defined conversion from const char * to std::string. Generally, user-defined conversions lose overload resolution process to standard conversions. This is what happens in your case as well.

If you need std::string version to be called here, provide an explicit overload for const char * type, and delegate the call to std::string version by converting the argument to std::string type explicitly

void Method(const char *paramater /* sic! */)
{
  Method(std::string(paramater));
}

Upvotes: 24

sellibitze
sellibitze

Reputation: 28097

Apart from the string issue, there's another one. int64_t and int8_t are (usually) typedefs. Since typedefs are just aliases, they may refer to the same type in which case overloading won't work. But this is rather unlikely in your case. Just wanted to mention it.

Upvotes: 1

Christian
Christian

Reputation: 4342

As Charles already pointed out, this happens due to an unwanted implicit conversion. If you want to avoid that, use a std::string constructor: Method(std::string("string")); or cast it to std::string:

Method(static_cast<std::string>("string"));

However, the order of your declarations isn't important. Also check your spelling of the word "parameter" ;)

Upvotes: 1

CB Bailey
CB Bailey

Reputation: 792129

The string literal "string" has type const char[] which can be implicity converted to bool. This is the best conversion candidate to one of your overloaded functions although it's not likely to be the most useful one.

If your intention was to have string literals be handled by the overload taking a std::string, then you need to add an overload taking a const char* and make the implementation call the std::string version.

Upvotes: 5

Related Questions