Strange behaviour in function overloading!

Discussion in 'C++' started by Paulo da Silva, Jul 2, 2007.

  1. 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);
    }
     
    Paulo da Silva, Jul 2, 2007
    #1
    1. Advertising

  2. Paulo da Silva wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jul 2, 2007
    #2
    1. Advertising

  3. Paulo da Silva

    Guest

    On Jul 2, 2:40 pm, Paulo da Silva <> wrote:
    > 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.
     
    , Jul 2, 2007
    #3
  4. Paulo da Silva

    shadowman Guest

    wrote:
    > On Jul 2, 2:40 pm, Paulo da Silva <> wrote:
    >> 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.
    >


    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
     
    shadowman, Jul 2, 2007
    #4
  5. Victor Bazarov escreveu:
    > Paulo da Silva wrote:
    >> Hi!
    >>
    >> Why doesn't this work?

    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.
    >
    >> If I change the name of the vector toLower for
    >> ex. to toLowerV it works! (GCC)
    >>
    >> Thanks.
    >> Paulo
    >>

    .....
    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>)'
     
    Paulo da Silva, Jul 3, 2007
    #5
  6. Paulo da Silva wrote:

    > Victor Bazarov escreveu:
    >> Paulo da Silva wrote:
    >>> Hi!
    >>>
    >>> Why doesn't this work?

    > 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.
    >>
    >>> If I change the name of the vector toLower for
    >>> ex. to toLowerV it works! (GCC)
    >>>
    >>> Thanks.
    >>> Paulo
    >>>

    > ....
    > 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&);
    .... static_cast<stringfun>(Aux::toLower)

    > }
    >
    > int main()
    > {
    > return 0;
    > }
    >


    --
    rbh
     
    Robert Bauck Hamar, Jul 3, 2007
    #6
  7. Robert Bauck Hamar escreveu:
    > Paulo da Silva wrote:
    >
    >> Victor Bazarov escreveu:
    >>> Paulo da Silva wrote:

    ....

    >> 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.

    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
     
    Paulo da Silva, Jul 3, 2007
    #7
  8. Paulo da Silva

    James Kanze Guest

    On Jul 3, 3:59 am, Paulo da Silva <> wrote:

    [Robert has already given the correct answer for the
    compiler error. However...]

    > pt2.h


    > 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).

    > return s;
    > }


    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 3, 2007
    #8
  9. Paulo da Silva

    Guest

    On Jul 2, 4:15 pm, shadowman <> wrote:
    > wrote:
    > > On Jul 2, 2:40 pm, Paulo da Silva <> wrote:
    > >> 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.

    >
    > 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.
     
    , Jul 3, 2007
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Iyer, Prasad C

    Overloading __init__ & Function overloading

    Iyer, Prasad C, Sep 30, 2005, in forum: Python
    Replies:
    3
    Views:
    6,413
    Fredrik Lundh
    Sep 30, 2005
  2. Fredrik Lundh
    Replies:
    0
    Views:
    451
    Fredrik Lundh
    Sep 30, 2005
  3. Steve Holden
    Replies:
    0
    Views:
    431
    Steve Holden
    Sep 30, 2005
  4. Iyer, Prasad C
    Replies:
    4
    Views:
    580
    John J. Lee
    Sep 30, 2005
  5. Fredrik Lundh
    Replies:
    0
    Views:
    402
    Fredrik Lundh
    Sep 30, 2005
Loading...

Share This Page