c++ - 无法使用非成员开始和结束函数编写基于范围的内容

标签 c++ for-loop c++11 g++ bitboard

我正在编写使用位板的代码。由于迭代位板的所有位是非常常见的操作,我决定编写一些迭代器类,并使用 c++0x 的基于范围的循环。 但是,g++(版本 4.6.3)告诉我 begin 没有匹配的函数。或 end .

我的代码:

#include <iostream>
#include <cinttypes>

class bitscan {
    uint64_t mask;
public:
    bitscan(uint64_t m) : mask(m) {}
    bool operator!=(bitscan it) const {return mask!=it.mask;}
    bitscan &operator++() {mask&=(mask-1);return *this;}
    int operator*() {return __builtin_ctzl(mask);}
};

bitscan begin(uint64_t m) {return m;}
bitscan end(uint64_t m) {return 0;}

int main() {
    uint64_t num=49;
    for (int i : num) std::cout<<i<<std::endl;
}

错误:

err.cpp: In function ‘int main()’:
err.cpp:18:15: error: no matching function for call to ‘begin(long unsigned int&)’
err.cpp:18:15: note: candidates are:
/usr/include/c++/4.6/initializer_list:86:5: note: template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)
/usr/include/c++/4.6/bits/range_access.h:87:5: note: template<class _Tp, long unsigned int _Nm> _Tp* std::begin(_Tp (&)[_Nm])
/usr/include/c++/4.6/bits/range_access.h:58:5: note: template<class _Container> decltype (__cont.begin()) std::begin(const _Container&)
/usr/include/c++/4.6/bits/range_access.h:48:5: note: template<class _Container> decltype (__cont.begin()) std::begin(_Container&)
err.cpp:18:15: error: no matching function for call to ‘end(long unsigned int&)’
err.cpp:18:15: note: candidates are:
/usr/include/c++/4.6/initializer_list:96:5: note: template<class _Tp> constexpr const _Tp* std::end(std::initializer_list<_Tp>)
/usr/include/c++/4.6/bits/range_access.h:97:5: note: template<class _Tp, long unsigned int _Nm> _Tp* std::end(_Tp (&)[_Nm])
/usr/include/c++/4.6/bits/range_access.h:78:5: note: template<class _Container> decltype (__cont.end()) std::end(const _Container&)
/usr/include/c++/4.6/bits/range_access.h:68:5: note: template<class _Container> decltype (__cont.end()) std::end(_Container&)

如果我用以下行替换循环:for (auto it=begin(num);it!=end(num);++it) std::cout<<*it<<std::endl; 它工作正常。

我的错误是什么?

最佳答案

在基于范围的 for 语句中,beginend 非成员函数仅通过参数相关查找(*) 查找(C++11 §6.5.4/1)。这意味着它们只能在与参数类型关联的命名空间中找到 (C++11 §3.4.2/2)。

基本类型,如 uint64_t,没有关联的命名空间,因此永远不会为它找到 beginend。您需要创建一个类类型来包装 uint64_t,以便可以通过依赖于参数的查找找到非成员 beginend 函数。


(*) 注意:beginend 实际上可以找到三种方式,但这是适用于您的场景的唯一方式。对于数组和具有名为 beginend 的成员函数的类也有特殊情况。

关于c++ - 无法使用非成员开始和结束函数编写基于范围的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11235050/

相关文章:

c++ - 使用自定义特征和 bool 类型的 c++11 枚举时出现 clang 编译错误

c++ - 如何在成员访问中使用依赖模板默认参数

c++ - sobel 过滤算法 (C++)(无库)

c++ - 使用 std::function 初始化匿名类成员变量

c++ - 具有相同键的 Poco HTMLForm 多个参数

javascript - For 循环和数组的一些数学问题

c++ - 使用 openmp 并行化 for 循环并替换 push_back

c++ - 在构造函数初始化列表上 move shared_ptr

c++ - 为什么 ATOMIC_FLAG_INIT 是假的?

c - 如何修复 “for loop initial declaration used outside C99 mode” GCC 错误?