考虑以下程序:
#include <iostream>
#include <iterator>
#include <vector>
#include <utility>
using namespace std; //just for convenience, illustration only
typedef pair<int, int> point; //this is my specialization of pair. I call it point
istream& operator >> (istream & in, point & p)
{
return in >> p.first >> p.second;
}
int main()
{
vector<point> v((istream_iterator<point>(cin)), istream_iterator<point>());
// ^^^ ^^^
//extra parentheses lest this should be mistaken for a function declaration
}
Run Code Online (Sandbox Code Playgroud)
这无法编译,因为只要ADL在命名空间std中找到operator >>,它就不再考虑全局范围,无论在std中找到的运算符是否是可行的候选者.这很不方便.如果我将operator >>的声明放入命名空间std(这在技术上是非法的),代码编译得很好.除了创建point我自己的类而不是将其定义为std命名空间中模板的特化之外,有没有办法解决这个问题?
提前致谢
在回答这个问题时(更好地阅读这个"重复"),我想出了以下解决方案来依赖运营商的名称:
[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>>{} );
}
Run Code Online (Sandbox Code Playgroud)
但是clang ++ 3.2和g ++ 4.8没有找到这个运算符(名称解析).
是否包含<iterator> …