Strange behaviour in function overloading!

P

Paulo da Silva

Hi!

Why doesn't this work? If I change the name of the vector toLower for
ex. to toLowerV it works! (GCC)

Thanks.
Paulo

..h
_______________
// Auxiliary functions
class Aux
{ private:

public:
static string &toLower(string &s);
static void toLower(vector<string> &vs); // Changing the name works!
};

..cpp
___________________

using namespace std;

string &Aux::toLower(string &s)
{ transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}

void Aux::toLower(vector<string> &vs) // Changing the name works!
{ transform(vs.begin(),vs.end(),vs.begin(),Aux::toLower);
}
 
V

Victor Bazarov

Paulo said:
Hi!

Why doesn't this work?

What clue tells you it doesn't work? An error message? Could you
be so kind as to supply the error message (or is it just too much
to ask)?
If I change the name of the vector toLower for
ex. to toLowerV it works! (GCC)

Thanks.
Paulo

.h
_______________
// Auxiliary functions
class Aux
{ private:

public:
static string &toLower(string &s);
static void toLower(vector<string> &vs); // Changing the name
works! };

Neither 'string' nor 'vector' is defined here. Did you include
the necessary headers?
.cpp
___________________

using namespace std;

string &Aux::toLower(string &s)
{ transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}

void Aux::toLower(vector<string> &vs) // Changing the name works!
{ transform(vs.begin(),vs.end(),vs.begin(),Aux::toLower);
}

This code doesn't compile (because 'string' or 'vector' are undefined).
Please post the COMPLETE code (and the rest needed, see FAQ 5.8).

V
 
I

ilikerps

Hi!

Why doesn't this work? If I change the name of the vector toLower for
ex. to toLowerV it works! (GCC)

Thanks.
Paulo

.h
_______________
// Auxiliary functions
class Aux
{ private:

public:
static string &toLower(string &s);
static void toLower(vector<string> &vs); // Changing the name works!

};


I may be wrong, but I don't think you can overload a function with a
different return type. It's true for Java, so it has a good chance of
being the same here. Try to change the return type of the void
function to string and see what happens.
 
S

shadowman

I may be wrong, but I don't think you can overload a function with a
different return type. It's true for Java, so it has a good chance of
being the same here. Try to change the return type of the void
function to string and see what happens.

Not exactly. You can specify different return types on overloaded
functions in C++ as long as the parameter list also differs. But you
cannot overload solely on return type
 
P

Paulo da Silva

Victor Bazarov escreveu:
See the compiler output below.

What clue tells you it doesn't work? An error message? Could you
be so kind as to supply the error message (or is it just too much
to ask)? No.
.....
Reposting a complete desierable compilable part:
pt2.h
#include <string>
#include <vector>

using namespace std;

// Auxiliary functions
class Aux
{ private:

public:
static string &toLower(string &s);
static void toLower(vector<string> &vs); // Changing the name works!
};

pt2.cpp
#include "pt2.h"

string &Aux::toLower(string &s)
{ transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}

void Aux::toLower(vector<string> &vs) // Changing the name works!
{ transform(vs.begin(),vs.end(),vs.begin(),Aux::toLower);
}

int main()
{
return 0;
}


This code doesn't compile (because 'string' or 'vector' are undefined).
:)

No!. This is part of a bigger program. The needed headers are there.
I think the compiler cannot determine which "toLower" to use in the 2nd.
transform.
Is there a way I can force it to use the first?
_____________________________________________________

pt2.cpp: In static member function 'static void
Aux::toLower(std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > >&)':
pt2.cpp:9: error: no matching function for call to
'transform(__gnu_cxx::__normal_iterator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >,
__gnu_cxx::__normal_iterator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >,
__gnu_cxx::__normal_iterator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >, <unresolved
overloaded function type>)'
 
R

Robert Bauck Hamar

Paulo said:
Victor Bazarov escreveu:
....
Reposting a complete desierable compilable part:
pt2.h
#include <string>
#include <vector>

using namespace std;

You should _never_ put this in a header file. You should IMHO _never_
use "using namespace std;" either if you can avoid it. If writing "std::"
is too much, rather include the names "using std::string;", but this too
not in header files.
// Auxiliary functions
class Aux
{ private:

public:
static string &toLower(string &s);
static void toLower(vector<string> &vs); // Changing the name works!
};

pt2.cpp
#include "pt2.h"

string &Aux::toLower(string &s)
{ transform(s.begin(),s.end(),s.begin(),::tolower);
return s;
}

void Aux::toLower(vector<string> &vs) // Changing the name works!
{ transform(vs.begin(),vs.end(),vs.begin(),Aux::toLower);

The problem is that std::transform is declared as:
template <typename Input, typename Output, typename Unary>
Output transform(Input a, Input b, Output o, Unary fun);

The compiler has, with the current standard, no way of knowing that fun must
be able to be called with a string. So Aux::toLower gives the compiler two
overloads. You must select the proper:

transform(vs.begin(), vs.end(), vs.begin(),
static_cast<string& (*)(string&)>(Aux::toLower));

This syntax might look awkward. One commonly uses typedefs to fix this:
typedef string& (*stringfun)(string&);
 
P

Paulo da Silva

Robert Bauck Hamar escreveu:
....


You should _never_ put this in a header file. You should IMHO _never_
use "using namespace std;" either if you can avoid it. If writing "std::"
is too much, rather include the names "using std::string;", but this too
not in header files.
Would you please tell me why if I am writing a small size application
and I have no need to use namespace stuff at all?
....
The compiler has, with the current standard, no way of knowing that fun must
be able to be called with a string. So Aux::toLower gives the compiler two
overloads. You must select the proper:

transform(vs.begin(), vs.end(), vs.begin(),
static_cast<string& (*)(string&)>(Aux::toLower));
That's exactly what I was looking for.
Thank you very much.

Paulo
 
J

James Kanze

[Robert has already given the correct answer for the
compiler error. However...]
string &Aux::toLower(string &s)
{ transform(s.begin(),s.end(),s.begin(),::tolower);

Where are you getting ::tolower from? The only standard place I
know is in <ctype.h> (formally, a deprecated header), which you
didn't include. And that function wouldn't be legal here
anyway; it results in undefined behavior, since it cannot
legally be called with a char (the result of dereferencing the
string iterator) on systems where char is signed (i.e. most).
 
I

ilikerps

Not exactly. You can specify different return types on overloaded
functions in C++ as long as the parameter list also differs. But you
cannot overload solely on return type

Ah, I see. That makes sense, thanks for telling me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top