1

I have an enum class "Suit" and defined a function "string to_string(Suit e)"

In another class, "Card", I have a member variable "my_Suit" and a member-function "to_string". This function calls the function "to_string" with "my_Suit" as a parameter.

At compilation I get an error that the compiler (g++) is looking for the function "Card::to_string(Suit&)", but this function doesn't exist (not within the scope mentioned, "Card::").

The error states :

error: no matching function for call to ‘Card::to_string(Suit&)’

candidate: std::__cxx11::string Card::to_string()

How do I make clear to the compiler that he must search for the function defined outside the class ?

This is a piece of code that gives the error at compilation. In reality, the code is divided between several header- and source-files, but the error stays the same.

#include <iostream>

/********************  enum class Suit  ********************/

enum class Suit
{
    Clubs, Spades, Hearts, Diamonds
};

std::string to_string(Suit e) 
{
    return ("calling 'to_string' function with Suit as parameter");
}

/********************  clas Card  ********************/

class Card
{

    private:
        Suit m_Suit;
    public:
        Card()  { m_Suit = Suit::Clubs; }

        std::string to_string() 
        {
            return ( to_string(m_Suit) );
        }
};

int main()
{
    std::cout << "Hello world!\n";
    return (0);
}
Community
  • 1
  • 1

2 Answers2

1

The name of the function to_string declared in the global name space is hidden by the declaration of the same name in the class scope of the class Card.

So use a qualified name. For example

    std::string to_string() 
    {
        return ( ::to_string(m_Suit) );
    }

Or use a using declaration like

    std::string to_string() 
    {
        using ::to_string;
        return ( to_string(m_Suit) );
    }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

As OP already suspected that's a scope issue.

The class Card has its own scope and provides a member Card::to_string().

Inside member functions all symbols are first tried to resolve in class scope before resolution steps to outer scopes if it failed.

In this case, the name resolution didn't fail but provided a candidate.

Unfortunately, the name resolution stops as soon as it found candidates – the wrong one in OPs case.

Hence, there is some explicit help necessary – a scope operator (::).

The fixed Card::to_string():

        std::string to_string() 
        {
            return ::to_string(m_Suit);
        }

The fixed sample of OP:

#include <iostream>

/********************  enum class Suit  ********************/

enum class Suit
{
    Clubs, Spades, Hearts, Diamonds
};

std::string to_string(Suit e) 
{
    return ("calling 'to_string' function with Suit as parameter");
}

/********************  class Card  ********************/

class Card
{

    private:
        Suit m_Suit;
    public:
        Card()  { m_Suit = Suit::Clubs; }

        std::string to_string() 
        {
            return ::to_string(m_Suit);
        }
};

int main()
{
    std::cout << Card().to_string() << '\n';
    return (0);
}

Output:

calling 'to_string' function with Suit as parameter

Live Demo on coliru

Btw. scope operators are resolved at compile time in general and doesn't have effect the runtime behavior.

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56