运算符“==”的模糊重载类型并没有真正的不同
Ambiguous overload for operator " == " Types don't really differ
我正在为玩具编译器(C++ 的子集)编写 AST,我遇到了这个特殊错误:
type.hpp:
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:
#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;
}
}
错误:
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 引用部分,然后说它无效。这真是令人费解,从昨天早上开始我就一直在苦思冥想。只是想知道我是否可以抓住一只手?
我也知道这个节点的设计可以改进。已经有了更好的 class 计划,但这个问题仍然是个问题。宝贝脚步。
干杯:)
在header中,友元函数是在命名空间内声明的,而源代码中的定义是在全局命名空间中。解决方案是将友元函数移出 header:
中的命名空间
// 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 建议的那样)将定义移动到命名空间内,方法是将其定义为:
bool evc::ast::operator==(const evc::ast::type& lhs, const evc::ast::type& rhs)
{
...
}
任一解决方案都可以解决歧义。
您有两个 operator==
,一个在命名空间 evc::ast
中,另一个
其他在全球命名空间。你的定义在全球
命名空间,因此在全局命名空间中找到一个,但是 ADL
也找到 evc::ast
中的那个,所以表达式是
模糊的。 (这正是错误消息所说的。它们列出了正在考虑的功能。)
我正在为玩具编译器(C++ 的子集)编写 AST,我遇到了这个特殊错误:
type.hpp:
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:
#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;
}
}
错误:
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 引用部分,然后说它无效。这真是令人费解,从昨天早上开始我就一直在苦思冥想。只是想知道我是否可以抓住一只手?
我也知道这个节点的设计可以改进。已经有了更好的 class 计划,但这个问题仍然是个问题。宝贝脚步。
干杯:)
在header中,友元函数是在命名空间内声明的,而源代码中的定义是在全局命名空间中。解决方案是将友元函数移出 header:
中的命名空间// 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 建议的那样)将定义移动到命名空间内,方法是将其定义为:
bool evc::ast::operator==(const evc::ast::type& lhs, const evc::ast::type& rhs)
{
...
}
任一解决方案都可以解决歧义。
您有两个 operator==
,一个在命名空间 evc::ast
中,另一个
其他在全球命名空间。你的定义在全球
命名空间,因此在全局命名空间中找到一个,但是 ADL
也找到 evc::ast
中的那个,所以表达式是
模糊的。 (这正是错误消息所说的。它们列出了正在考虑的功能。)