依赖名称解析&命名空间std /标准库
Dependent name resolution & namespace std / Standard Library
在回答这个SO问题时(最好读这个"副本"),我提出了以下解决算子的依赖名称解析的方法:
[temp.dep.res]/1:
在解析依赖名称时,考虑来自以下来源的名称:
- 在模板定义处可见的声明。
- 与实例化上下文(14.6.4.1)和定义上下文的函数参数类型相关联的命名空间的声明。
#include <iostream>
#include <utility>
// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<int,int>& p)
{
s >> p.first >> p.second;
return s;
}
// include definition of `istream_iterator` only after declaring the operator
// -> temp.dep.res/1 bullet 1 applies??
#include <iterator>
#include <map>
#include <fstream>
int main()
{
std::ifstream in("file.in");
std::map<int, int> pp;
pp.insert( std::istream_iterator<std::pair<int, int>>{in},
std::istream_iterator<std::pair<int, int>>{} );
}
但是clang++ 3.2和g++ 4.8没有找到这个操作符(名称解析)。
<iterator>
的包含是否定义了"模板的定义点"istream_iterator
?
编辑:正如Andy Prowl指出的,这与标准库无关,而是与名称查找(可以通过模仿多个operator>>
的标准库来证明,至少有一个在假istream
的命名空间中)。
Edit2:一个解决方法,使用[basic.lookup]。/2子弹头2
#include <iostream>
#include <utility>
// can include <iterator> already here,
// as the definition of a class template member function
// is only instantiated when the function is called (or explicit instantiation)
// (make sure there are no relevant instantiations before the definition
// of the operator>> below)
#include <iterator>
struct my_int
{
int m;
my_int() : m() {}
my_int(int p) : m(p) {}
operator int() const { return m; }
};
// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<my_int,my_int>& p)
{
s >> p.first.m >> p.second.m;
return s;
}
#include <map>
#include <fstream>
int main()
{
std::ifstream in("file.in");
std::map<int, int> pp;
pp.insert( std::istream_iterator<std::pair<my_int, my_int>>{in},
std::istream_iterator<std::pair<my_int, my_int>>{} );
}
当然,您也可以使用自己的pair
类型,只要解决方法在自定义operator>>
的名称空间中引入一个相关的类。
这里的问题是,对operator >>
的调用是在std
名称空间内的某个地方,而参数类型所在的名称空间是std
。
如果编译器可以在调用发生的名称空间或参数类型所在的名称空间中找到operator >>
(在本例中都是std
名称空间),无论重载解析是否可行(在名称查找之后执行),它都不会在父名称空间中寻找operator >>
的更多重载。
不幸的是,您的operator >>
位于全局命名空间中,因此找不到。
相关文章:
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- 标准::unordered_map 中的 std::array 的值初始化
- 标准::在双类和类的 std::p air 上更大
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- 无法重置 std::shared_ptr 标准::设置<>中的对象...为什么?
- 连接和压缩标准::vector<std::字符串的最佳方法>
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 如何将标准::矢量插入具有自定义排序功能的 std::set 中
- 如果有标准::屏障,为什么是 std::闩锁?
- 'std::filesystem::p ath' 没有标准哈希吗?
- 使用标准库在 c++11 中使用 std::tie 提取嵌套在元组中的元组
- 标准库中是否有相当于 Rust 的 'std::mem::d rop' 的C++?
- 在使用标准向量函数时引发'std::bad_alloc'实例后调用的终止
- 为什么C++标准中没有 std::basic_string 类的构造函数,其参数类型为 std::string_view
- C++标准是否保证 std::string::resize(new_size) 在new_size不大于旧标准时不会导致
- C 是否具有对两个STD :: sets,vectors等进行三角比较的标准方法
- 用STD = C 11或其他标准编译Boost,例如Ash C 14
- 安装 GCC 7.1 是否会在标准库中包含 std::is_base_of_v
- 依赖名称解析&命名空间std /标准库
- 这个boost::元组代码可以转换为纯std::标准库代码吗?