c++ - 在 ADL 期间如何防止遮盖?

标签 c++ templates argument-dependent-lookup

假设我有一个类扩展了一个(STL)容器并提供了一个惯用的 begin成员函数:

#include <vector>

template <typename Cont>
struct Bar {
    Cont c;
    auto my_begin() { return begin(c); }
};

int main() {
    Bar<std::vector<int>> b;
    b.my_begin();
}
通过 ADL,我不必指定 std::begin() 之前称呼。这很好,因为 std::begin(v)总是会尝试调用v.begin() ,用户可能想要使用没有 .begin() 的自定义容器接口(interface),所以如果他定义了自己的自由函数begin(v) , Bar会使用它。
但是,如果我重命名 my_begin,ADL 似乎将不再起作用至begin也好似被蒙上了一层阴影。编译器只会提示它在类范围内找不到匹配的调用:
prog.cc: In instantiation of 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]':
prog.cc:11:13:   required from here
prog.cc:6:27: error: use of 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]' before deduction of 'auto'
    6 |     auto begin() { return begin(c); }
      |                           ^~~~~
prog.cc:6:32: error: no matching function for call to 'Bar<std::vector<int> >::begin(std::vector<int>&)'
    6 |     auto begin() { return begin(c); }
      |                           ~~~~~^~~
prog.cc:6:10: note: candidate: 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]'
    6 |     auto begin() { return begin(c); }
      |          ^~~~~
prog.cc:6:10: note:   candidate expects 0 arguments, 1 provided
当然,写 std::begin ,代码将再次运行,但这只会显示 ADL 的排除。除了重命名成员函数,我还能做什么?

最佳答案

您可以只使用两步方法:

    auto begin() { 
        using std::begin;   //1
        return begin(c);    //2
    }
1 : 带std::begin考虑到2 : 如果 cbegin()在其命名空间中,调用它,否则默认为 std::begin()您可以阅读更多信息 here

关于c++ - 在 ADL 期间如何防止遮盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63337303/

相关文章:

django - urlencode 过滤器在 Django 模板中不起作用

templates - C++ 部分模板特化结合 std::is_base_of 和 std::enable_if

c++ - C++ 中的类模板和友元

c++ - 使用模板化基类型对派生结构进行结构初始化

c++ - STL背后的设计原理

c++ - PCRE多行匹配问题

c++ - Bjarne 对这个 ADL 示例是否有错误,或者我有编译器错误?

c++ - 将文件中的多个输入分隔为偶数或奇数

c++ - 模板代理方法无法编译

c++ - 重载左移运算符