首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运算符“==”类型的模糊重载并没有真正的不同

运算符“==”类型的模糊重载并没有真正的不同
EN

Stack Overflow用户
提问于 2015-01-22 11:11:25
回答 2查看 2.5K关注 0票数 0

我正在为一个玩具编译器(C++的子集)编写AST,我遇到了这个特殊的错误:

type.hpp:

代码语言:javascript
复制
namespace evc
{
  namespace ast
  {
    enum class type_t;
    struct type : public ast
    {
      using ast::ast;
      type_t m_type;
      type* m_subtype; // for const, array, references, pointers, etc.

      // Checks if two types are the the same or not
      friend bool operator==(const evc::ast::type& lhs, const evc::ast::type& rhs);
    };
  }
}

type.cpp:

代码语言:javascript
复制
#include <ast/type.hpp>
bool operator==(const evc::ast::type& lhs, const evc::ast::type& rhs)
{
  if (lhs.m_type == rhs.m_type)
  {
    if (lhs.m_subtype != nullptr && rhs.m_subtype != nullptr)
    {
      return (*lhs.m_subtype == *rhs.m_subtype);
    }
    else
    {
      return (lhs.m_subtype == nullptr && rhs.m_subtype == nullptr);
    }
  }
  else
  {
    return false;
  }
}

错误:

代码语言:javascript
复制
g++ -Wall -Wextra -Wc++11-compat -pedantic -Werror -std=c++14 -I inc

src/ast/type.cpp: In function 'bool operator==(const evc::ast::type&, const evc::ast::type&)':
src/ast/type.cpp:52:36: error: ambiguous overload for 'operator==' (operand types are 'evc::ast::type' and 'evc::ast::type')
             return (*lhs.m_subtype == *rhs.m_subtype);
                                    ^
src/ast/type.cpp:52:36: note: candidates are:
src/ast/type.cpp:46:6: note: bool operator==(const evc::ast::type&, const evc::ast::type&)
 bool operator==(const evc::ast::type& lhs, const evc::ast::type& rhs)
      ^
In file included from src/ast/type.cpp:1:0:
inc/ast/type.hpp:37:25: note: bool evc::ast::operator==(const evc::ast::type&, const evc::ast::type&)
             friend bool operator==(const evc::ast::type& lhs, const evc::ast::type& rhs);

我理解什么是歧义(在编写编译器时,您可能希望我会!),但我不明白为什么它是模棱两可的。在我看来,编译器正在删除const引用部分,然后说它是无效的。这真是令人费解,从昨天早上开始我就一直在想这件事。只是想知道我能不能抓住一只手?

我也知道这个节点的设计是可以改进的。已经有一个更好的班级计划出来,但这个问题仍将是一个问题。婴儿步子。

干杯:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-22 11:27:06

您有两个operator==,一个在命名空间evc::ast中,另一个在全局名称空间中。您的定义位于全局命名空间中,因此在全局命名空间中找到了定义,但ADL也在evc::ast中找到了该名称空间,因此表达式是不明确的。(这正是错误消息所说的。列出正在考虑的职能。)

票数 3
EN

Stack Overflow用户

发布于 2015-01-22 11:23:51

在标头中,朋友函数在名称空间中声明,而源中的定义在全局命名空间中。解决方案是将friend函数移出标头中的命名空间:

代码语言:javascript
复制
// Predeclaration
namespace evc { namespace ast { struct type; } }

// Declare the friend function in the global namespace
bool operator==(const evc::ast::type& lhs, const evc::ast::type& rhs);

namespace evc
{
    namespace ast
    {
        enum class type_t;
        struct type : public ast
        {
            using ast::ast;
            type_t m_type;
            type* m_subtype; // for const, array, references, pointers, etc.

            // Explicitly state the operator is declared in the global namespace
            friend bool ::operator==(const evc::ast::type& lhs, const evc::ast::type& rhs);
        };
    }
}

或者(正如James建议的那样)通过将定义定义为:

代码语言:javascript
复制
bool evc::ast::operator==(const evc::ast::type& lhs, const evc::ast::type& rhs)
{
    ...
}

任何一种解决方案都将解决歧义问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28087319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档