1

我有一个枚举类“Suit”并定义了一个函数“string to_string(Suit e)”

在另一个类“Card”中,我有一个成员变量“my_Suit”和一个成员函数“to_string”。此函数以“my_Suit”作为参数调用函数“to_string”。

在编译时,我得到一个错误,编译器 (g++) 正在寻找函数“Card::to_string(Suit&)”,但这个函数不存在(不在提到的范围内,“Card::”)。

错误状态:

错误:没有匹配函数调用'Card::to_string(Suit&)'</p>

候选人:std::__cxx11::string Card::to_string()

如何让编译器清楚他必须搜索在类外定义的函数?

这是一段在编译时给出错误的代码。实际上,代码分为几个头文件和源文件,但错误保持不变。

#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);
}
4

2 回答 2

1

全局命名空间中声明的函数to_string的名称被Card类的类作用域中的同名声明所隐藏。

因此,请使用限定名称。例如

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

或使用 using 声明,如

    std::string to_string() 
    {
        using ::to_string;
        return ( to_string(m_Suit) );
    }
于 2020-01-25T11:28:43.593 回答
1

正如 OP 已经怀疑这是一个范围问题。

class Card有自己的范围并提供一个成员Card::to_string()

在成员函数内部,如果失败,则首先尝试在类范围内解析所有符号,然后再解析到外部范围。

在这种情况下,名称解析并没有失败,而是提供了一个候选者。

不幸的是,名称解析在找到候选者后立即停止——在 OPs 案例中是错误的。

因此,需要一些明确的帮助——范围运算符 ( ::)。

固定Card::to_string()

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

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);
}

输出:

calling 'to_string' function with Suit as parameter

coliru 现场演示

顺便提一句。范围运算符通常在编译时解析,并且不会影响运行时行为。

于 2020-01-25T11:30:15.500 回答