'operator==' 与自己的 class 和 std::string_view 的不明确重载
Ambiguous overload for 'operator==' with own class and std::string_view
我在 namespace N
中创建了一个名为 MyClass
的 class。现在我在 namespace N
.
中定义了一个全局 operator==
namespace N
{
class MyClass
{
// member function begin()
// member function end()
// content omitted
}
template<typename T>
bool operator==(const MyClass& a_mc, const T& a_other)
{
using namespace std;
return std::equal(a_mc.begin(), a_mc.end(), begin(a_other));
}
}
这会导致其他代码无法编译(忽略从堆栈中包含):
error: ambiguous overload for 'operator==' (operand types are
'std::basic_string_view' and 'const char [3]')
note: candidate: 'bool N::operator==(const N::MyClass&, const T&)
[with T = char [3]]'
note: candidate: 'constexpr bool
std::operator==(std::basic_string_view<_CharT, _Traits>,
std::__detail::__idt >) [with
_CharT = char; _Traits = std::char_traits; std::__detail::__idt > =
std::basic_string_view]' 479 |
operator==(basic_string_view<_CharT, _Traits> __x
为什么还要考虑 N::operator==
?
--
编辑遇到问题的第一个代码是
bool N::MyClass::f(const std::string_view& a_thing)
{return a_thing.substr(0,2) == "XY";}
--
最小工作示例:
#include <algorithm>
#include <string_view>
#include <type_traits>
namespace N
{
struct MyClass
{
MyClass() noexcept = default;
template<typename T,
typename = std::void_t<decltype(T{}.data())>,
typename = std::void_t<decltype(T{}.size())>>
MyClass(const T& a_source)
{}
const char* begin() const { return 0; } // stub
const char* end() const { return 0; } // stub
bool f(const std::string_view& a_thing);
};
template<typename T>
bool operator==(const MyClass& a_mc, const T& a_other)
{
using namespace std;
return std::equal(a_mc.begin(), a_mc.end(), begin(a_other));
}
bool MyClass::f(const std::string_view& a_thing)
{
return a_thing.substr(0,2) == "XY";
}
}
用
编译
g++ -std=c++17 example.cpp
MyClass 有一个与 std::string_view
一起使用的模板构造函数。
由于未标记构造函数 explicit
允许编译器将其用于隐式转换。
这意味着当你这样做时
bool N::MyClass::f(const std::string_view& a_thing)
{return a_thing.substr(0,2) == "XY";}
允许编译器将 a_thing.substr(0,2)
转换为 MyClass
,然后它可用于调用您的 bool operator==
.
避免这种情况的一种方法是使 MyClass
的构造函数显式化。
template<typename T,
typename = std::void_t<decltype(T{}.data())>,
typename = std::void_t<decltype(T{}.size())>>
explicit MyClass(const T& a_source)
{}
我在 namespace N
中创建了一个名为 MyClass
的 class。现在我在 namespace N
.
operator==
namespace N
{
class MyClass
{
// member function begin()
// member function end()
// content omitted
}
template<typename T>
bool operator==(const MyClass& a_mc, const T& a_other)
{
using namespace std;
return std::equal(a_mc.begin(), a_mc.end(), begin(a_other));
}
}
这会导致其他代码无法编译(忽略从堆栈中包含):
error: ambiguous overload for 'operator==' (operand types are 'std::basic_string_view' and 'const char [3]')
note: candidate: 'bool N::operator==(const N::MyClass&, const T&) [with T = char [3]]'
note: candidate: 'constexpr bool std::operator==(std::basic_string_view<_CharT, _Traits>, std::__detail::__idt >) [with _CharT = char; _Traits = std::char_traits; std::__detail::__idt > = std::basic_string_view]' 479 |
operator==(basic_string_view<_CharT, _Traits> __x
为什么还要考虑 N::operator==
?
--
编辑遇到问题的第一个代码是
bool N::MyClass::f(const std::string_view& a_thing)
{return a_thing.substr(0,2) == "XY";}
--
最小工作示例:
#include <algorithm>
#include <string_view>
#include <type_traits>
namespace N
{
struct MyClass
{
MyClass() noexcept = default;
template<typename T,
typename = std::void_t<decltype(T{}.data())>,
typename = std::void_t<decltype(T{}.size())>>
MyClass(const T& a_source)
{}
const char* begin() const { return 0; } // stub
const char* end() const { return 0; } // stub
bool f(const std::string_view& a_thing);
};
template<typename T>
bool operator==(const MyClass& a_mc, const T& a_other)
{
using namespace std;
return std::equal(a_mc.begin(), a_mc.end(), begin(a_other));
}
bool MyClass::f(const std::string_view& a_thing)
{
return a_thing.substr(0,2) == "XY";
}
}
用
编译g++ -std=c++17 example.cpp
MyClass 有一个与 std::string_view
一起使用的模板构造函数。
由于未标记构造函数 explicit
允许编译器将其用于隐式转换。
这意味着当你这样做时
bool N::MyClass::f(const std::string_view& a_thing)
{return a_thing.substr(0,2) == "XY";}
允许编译器将 a_thing.substr(0,2)
转换为 MyClass
,然后它可用于调用您的 bool operator==
.
避免这种情况的一种方法是使 MyClass
的构造函数显式化。
template<typename T,
typename = std::void_t<decltype(T{}.data())>,
typename = std::void_t<decltype(T{}.size())>>
explicit MyClass(const T& a_source)
{}