【发布时间】:2016-07-28 14:10:26
【问题描述】:
我定义operator==如下:
template <class State>
bool operator==(const std::shared_ptr<const State> &lhs,
const std::shared_ptr<const State> &rhs) {
return *lhs == *rhs;
}
此运算符未实例化(在gdb 中,我无法在返回语句上设置断点——该行不存在)。
但是,这个操作符应该被这行调用的std::find使用:
return std::find(v.begin(), v.end(), el) != v.end();
我在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> &
这不符合我的模板化 operator== 和 State 是 IncWorst 吗?
我实现了一个如下的玩具示例并且示例有效,所以我不明白为什么真正的代码没有。
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;
}
【问题讨论】:
-
只是一个猜测,但您确定该模板在您调用 find 的文件中可供编译器使用吗?换句话说,它是#included 还是定义在该文件的顶部?
-
确实如此。我检查了预处理器的输出以确保。
-
这似乎是解决问题的错误方法。无需为您的一个用例定义全局 == 运算符,只需将 lambda 比较器传递给
std::find_if。不过,仍然对这不起作用的技术原因感到好奇。 -
令我感兴趣的是,您在全局命名空间中的
operator==与std命名空间中定义的operator==具有几乎 相同的函数签名--stdoperator==用于 both 参数上的shared_ptr模板,并且没有用于shared_ptrs 的const模板参数。不过,我在这个上使用了 templatetypedef:不要创建适用于所有shared_ptr类型的全局函数,请指明您想要哪种相等。默认的将被假定为您的代码的所有读者都使用的那个。我会使用的 的owner_lesseq版本 -
@templatetypedef 我有很多代码依赖于测试相等性共享指向 const 状态的指针。我不想将它全部更改为使用 lambdas。当然,我会在未来让这个模板更加精确,只捕获状态,而不是过多地污染全局命名空间。
标签: c++ templates operator-overloading