C++ 用于基元类型的基于范围的

C++ 用于基元类型的基于范围的,c++,c++14,language-lawyer,C++,C++14,Language Lawyer,正如前面提到的,OP试图让下面的语句对这些数字进行迭代 for (int n : 10) cout << n << endl; 关于begin_expr和end_expr的说明如下: begin_expr和end_expr的定义如下: 如果range_表达式是数组类型的表达式,则[…] 如果range_表达式是C类[…]类型的表达式 否则,begin_expr是begin(\uu range),end_expr是end(\uu range),它们通过参数相关查

正如前面提到的,OP试图让下面的语句对这些数字进行迭代

for (int n : 10)
    cout << n << endl;
关于begin_expr和end_expr的说明如下:

begin_expr和end_expr的定义如下:

  • 如果range_表达式是数组类型的表达式,则[…]
  • 如果range_表达式是C类[…]类型的表达式
  • 否则,begin_expr是
    begin(\uu range)
    ,end_expr是
    end(\uu range)
    ,它们通过参数相关查找找到(不执行非ADL查找)
在我们的例子中,range_表达式是
10
,它既不是数组类型,也不是类类型,所以最后一个项目符号应该生效。所以我们提供了这些函数

auto begin(int) {
    return boost::counting_iterator<int>(0);
}

auto end(int n) {
    return boost::counting_iterator<int>(n);
}
(对于
end
,也有相同的消息)。然而,如果我根据描述更改基于范围的for循环,我会得到以下结果,这是可行的

{
    auto && __range = 10;
    for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) {
        int t = *__begin;
        std::cout << t << std::endl;
    }
}
{
自动范围=10;
对于(自动开始=开始(\uu范围),\uu结束=结束(\uu范围);\uu开始!=\uu结束;++\uu开始){
int t=*\u开始;
std::cout关键短语是:

通过参数相关查找找到(不执行非ADL查找)

int
没有名称空间。不,甚至没有全局名称空间。因此,基于名称空间的查找找不到任何内容

为了更具体地说明规范,[basic.lookup.argdep]/2.1说:

如果T是基本类型,则其相关的名称空间集和类集都是空的

由于没有相关的名称空间或类,ADL无法工作


用户定义的文本返回一个计数范围会更好地处理这个问题。因此,您可以键入
10_rng
,这将产生一个计数范围。

Uh,鉴于我在一项研究中所做的努力,希望有更复杂的内容:-)。谢谢。@Zereges:ADL唯一的基于范围的查找规则正是基于范围的for中存在规则#1的原因。这就是为什么有专门针对数组上的范围的特殊措辞。毕竟,
std::begin/end
对于数组是重载的,那么为什么要对数组使用
for
的措辞呢?因为规则#3无法找到它们,因为它只是ADL。你只是……问了同样的问题你链接到了什么?@Barry实际上不是,我链接的问题是问如何做到这一点,而我是问为什么这个想法行不通。这个问题回答不了你的问题吗?@Barry是的,但在我开始写这个问题时,它不在那里。
main.cpp: In function 'int main()':
main.cpp:17:18: error: 'begin' was not declared in this scope
     for (int t : 10)
                  ^~
main.cpp:17:18: note: suggested alternatives:
main.cpp:5:6: note:   'begin'
 auto begin(int) {
      ^~~~~

In file included from /usr/local/include/c++/7.2.0/vector:66:0,
                 from main.cpp:1:
/usr/local/include/c++/7.2.0/bits/range_access.h:105:37: note:   'std::begin'
   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);
                                     ^~~~~
{
    auto && __range = 10;
    for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) {
        int t = *__begin;
        std::cout << t << std::endl;
    }
}