HC4*_*ica 6 c++ foreach argument-dependent-lookup c++11
所述的C++ 0x标准工作草案状态(部分6.5.4)关于开始以下()和()结束,在是隐式的呼叫的范围为基础的循环:
使用参数依赖查找(3.4.2)查找'begin'和'end'.出于此名称查找的目的,名称空间std是关联的名称空间.
我读这个的方式,这意味着为begin()和end()调用设置的重载决议包括以下所有内容:
那是对的吗?
g ++ 4.6的行为似乎与这种解释不一致.对于此代码:
#include <utility>
template <typename T, typename U>
T begin(const std::pair<T, U>& p);
template <typename T, typename U>
U end(const std::pair<T, U>& p);
int main()
{
std::pair<int*, int*> p;
for (int x : p)
;
}
Run Code Online (Sandbox Code Playgroud)
它给出了以下错误:
adl1.cpp: In function 'int main()':
adl1.cpp:12:18: error: No match for 'begin(pair<int *, int *> &)'
adl1.cpp:12:18: candidate is:
/usr/local/lib/gcc/i686-pc-linux-
gnu/4.6.0/../../../../include/c++/4.6.0/initializer_list:86:38: template<
class _Tp> constexpr const _Tp * begin(initializer_list<_Tp>)
adl1.cpp:12:18: error: No match for 'end(pair<int *, int *> &)'
adl1.cpp:12:18: candidate is:
/usr/local/lib/gcc/i686-pc-linux-
gnu/4.6.0/../../../../include/c++/4.6.0/initializer_list:96:36: template<
class _Tp> constexpr const _Tp * end(initializer_list<_Tp>)
Run Code Online (Sandbox Code Playgroud)
这表明,它正在考虑只在空间std重载,而不是在全局命名空间重载.
但是,如果我使用在全局命名空间中声明的自己的对类,则编译很好:
template <typename T, typename U>
struct my_pair
{
T first;
U second;
};
template <typename T, typename U>
T begin(const my_pair<T, U>& p);
template <typename T, typename U>
U end(const my_pair<T, U>& p);
int main()
{
my_pair<int*, int*> p;
for (int x : p)
;
}
Run Code Online (Sandbox Code Playgroud)
作为最后的测试,我尝试将my_pair放在一个单独的命名空间中:
namespace my
{
template <typename T, typename U>
struct my_pair
{
T first;
U second;
};
}
template <typename T, typename U>
T begin(const my::my_pair<T, U>& p);
template <typename T, typename U>
U end(const my::my_pair<T, U>& p);
int main()
{
my::my_pair<int*, int*> p;
for (int x : p)
;
}
Run Code Online (Sandbox Code Playgroud)
我再次得到错误:
adl3.cpp: In function 'int main()':
adl3.cpp:22:18: error: 'begin' was not declared in this scope
adl3.cpp:22:18: suggested alternative:
adl3.cpp:14:35: 'begin'
adl3.cpp:22:18: error: 'end' was not declared in this scope
adl3.cpp:22:18: suggested alternative:
adl3.cpp:17:33: 'end'
Run Code Online (Sandbox Code Playgroud)
因此,它似乎只考虑名称空间std和其他相关名称空间中的重载,而不考虑调用站点范围内的重载(上面列表中的第一个项目符号点).
这是一个gcc错误,还是我误解了标准?
如果是后者,这是否意味着将std :: pair对象视为基于范围的for循环中的范围是不可能的(不会重载std :: begin()和std :: end(),如果我不是错误是不允许的)?
我首先报告说这对我来说看起来像是一个 gcc bug。现在看来,连 for 循环规范的这一部分也不清楚,并且已经向委员会提出了质询。
看起来基于范围的 for 循环规则很快就会改变:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3257.pdf
我不确定会选择 N3257 中列出的哪个选项。
| 归档时间: |
|
| 查看次数: |
1614 次 |
| 最近记录: |