【问题标题】:Function-definition in class requires same function in other class : compilation error类中的函数定义需要其他类中的相同函数:编译错误
【发布时间】:2020-05-11 12:00:31
【问题描述】:

我有一个枚举类“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&)'

候选人: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);
}

【问题讨论】:

标签: c++ compiler-errors scope name-lookup using-declaration


【解决方案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

Live Demo on coliru

顺便说一句。作用域运算符通常在编译时解析,不会影响运行时行为。

【讨论】:

    【解决方案2】:

    在全局命名空间中声明的函数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) );
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多