[英]Why does my templated operator== not get used?
I have defined operator==
as follows: 我已经定义了operator==
,如下所示:
template <class State>
bool operator==(const std::shared_ptr<const State> &lhs,
const std::shared_ptr<const State> &rhs) {
return *lhs == *rhs;
}
This operator does not get instantiated (in gdb
, I cannot set the break-point on the return statement -- the line does not exist). 此运算符不会实例化(在gdb
,我无法在return语句上设置断点-该行不存在)。
However, this operator should be used by std::find
called in this line: 但是,此操作符应由以下行中调用的std::find
使用:
return std::find(v.begin(), v.end(), el) != v.end();
I checked the type of v
in the above line in gdb
: 我在gdb
的上一行中检查了v
的类型:
(gdb) whatis v
type = const std::vector<std::shared_ptr<Domains::IncWorst const>> &
(gdb) whatis el
type = const std::shared_ptr<Domains::IncWorst const> &
Doesn't this match my templated operator==
with State
being IncWorst
? 这不匹配我的模板operator==
且State
为IncWorst
吗?
I implemented a toy example as follows and the example works, so I cannot understand why the real code does not. 我实现了一个玩具示例,并且该示例可以正常工作,因此我无法理解为什么真正的代码不起作用。
template<class V, typename T>
bool in(const V &v, const T &el) {
return std::find(v.begin(), v.end(), el) != v.end();
}
struct MyState {
MyState(int xx) : x(xx) {}
bool operator==(const MyState &rhs) const {
return x == rhs.x;
}
int x;
};
template <class State>
bool operator==(const std::shared_ptr<const State> &lhs,
const std::shared_ptr<const State> &rhs) {
return *lhs == *rhs;
}
int main() {
std::vector<std::shared_ptr<const MyState>> v{
std::make_shared<const MyState>(5)};
auto p = std::make_shared<const MyState>(5);
std::cout << in(v, p) << std::endl; // outputs 1
return 0;
}
Your operator==
template is in the wrong namespace. 您的operator==
模板位于错误的名称空间中。
In order to be found by ADL, it must be either in the std
namespace (which would be illegal, per [ namespace.std ]/1 ) or in Domains
(per [basic.lookup.argdep] /2 ). 为了被ADL查找,它必须位于std
命名空间中(根据[[ namespace.std ] / 1 ,这是非法的)或在Domains
(根据[basic.lookup.argdep] / 2 )。
However, this is still highly dangerous, since if any template performing an equality comparison (eg but not limited to std::find
) is instantiated both before and after your operator==
template is declared, your whole program will be invalid per [temp.point] /8 and [basic.def.odr] /6 . 但是,这仍然是非常危险的,因为如果在声明operator==
模板之前和之后都实例化了执行相等比较的模板(例如但不限于std::find
),则每个[temp .point] / 8和[basic.def.odr] / 6 。
If you must provide operator overload templates for std::shared_ptr
s of your types, prefer to explicitly instantiate them after the declaration of each class, such that there is less chance of a template being instantiated somewhere the class is not visible: 如果必须为您的类型的std::shared_ptr
提供运算符重载模板,则最好在每个类的声明之后显式实例化它们,这样可以减少在类不可见的地方实例化模板的机会:
struct MyState {
// ...
};
template bool operator==<MyState>(
const std::shared_ptr<MyState const>&,
const std::shared_ptr<MyState const>&);
This could still be problematic if someone forward-declares MyState
somewhere else, but it's probably the best you can do. 如果有人在其他地方转发声明MyState
,这仍然可能会出现问题,但这可能是您可以做的最好的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.