如何在不同命名空间中与候选人拨打ADL的歧义

How to disambiguate ADL call with candidates in different namespaces?

本文关键字:候选人 ADL 歧义 命名空间      更新时间:2023-10-16

给定以下类:

struct foo : public boost::static_visitor<> {
    void do_stuff(int item) {}
}

现在,在另一个上下文中,我有一个std::vector<foo>,并希望在其上执行以下算法:

using namespace std::tr1;
using namespace std::tr1::placeholders;
std::vector<foo> items;
std::for_each(items.begin(), items.end(), bind(&foo::do_stuff, _1));

这会引发一条巨大的模板错误消息,归结为对std::tr1::refboost::ref的模棱两可的呼叫。如果我从foo中删除基类boost::static_visitor,则一切正常。

据我了解,问题在于,在std::tr1::bind的代码中,ref(arg)在没有名称空间资格的情况下被调用。由于bind在命名空间std::tr1中,因此std::tr1::ref处于范围。但是,由于foo从名称空间boost中的类中继承,因此ADL也找到了boost::ref。理解正确吗?

由于我需要那个基类(它是boost.variant的一部分),所以我需要在这里知道是否有任何方法可以从我的代码中删除此调用?

注意:我在这里陷于C 03,因此使用std::tr1

Jesse提供了一个答案的链接,该链接是解决此问题的解决方案。但是,在这种特殊情况下,我提出了另一种解决方案。boost::static_visitor只有一个功能,它提供了result_type Typedef。可以轻松地手动添加,并且不再需要基类。