C++ 我应该在哪里定义运算符>&燃气轮机;对于我的std::pair专业?

C++ 我应该在哪里定义运算符>&燃气轮机;对于我的std::pair专业?,c++,stl,template-specialization,argument-dependent-lookup,C++,Stl,Template Specialization,Argument Dependent Lookup,考虑以下计划: #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 ca

考虑以下计划:

#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
}
#包括
#包括
#包括
#包括
使用名称空间std//仅为方便起见,仅作说明
typedef对点//这是我的专业配对。我称之为重点
istream&operator>>(istream&in,point&p)
{
返回>>p.first>>p.second;
}
int main()
{
向量v((istream_迭代器(cin)),istream_迭代器();
//             ^^^                         ^^^        
//额外的括号,以免将其误认为函数声明
}

此编译失败,因为一旦ADL在命名空间STD中找到运算符>,它就不会考虑全局范围,而不管STD中找到的操作符是否是可行的候选对象。这相当不方便。如果我将运算符>>的声明放在命名空间std中(这在技术上是非法的),那么代码将按照预期编译。除了使

point
成为我自己的类,而不是将其定义为std名称空间中模板的专门化之外,还有其他方法解决这个问题吗


提前感谢

禁止在
命名空间std
中添加超负荷的
运算符>
,但有时允许添加模板专用化

但是,这里没有用户定义的类型,标准类型上的运算符也不需要重新定义。专业化
操作员>>(istream和,配对)
是合理的


[namespace.std]
节(n3290第17.6.4.2.1节)规定

< C++程序的行为是不明确的,如果它将声明或定义添加到命名空间<代码> STD<代码>或命名空间>代码> STD< /COD>中的命名空间,除非另有说明。strong>仅当声明依赖于用户定义的类型且专门化满足原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板专门化添加到命名空间
std


(emphasis mine)

禁止在
命名空间std
中添加超负荷的
操作符>
,但有时允许添加模板专门化

但是,这里没有用户定义的类型,标准类型上的运算符也不需要重新定义。专业化
操作员>>(istream和,配对)
是合理的


[namespace.std]
节(n3290第17.6.4.2.1节)规定

< C++程序的行为是不明确的,如果它将声明或定义添加到命名空间<代码> STD<代码>或命名空间>代码> STD< /COD>中的命名空间,除非另有说明。strong>仅当声明依赖于用户定义的类型且专门化满足原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板专门化添加到命名空间
std


(强调我的问题)

你的回答是否意味着我的问题的答案是否定的,我应该把
作为一个单独的类?对于Ben Voigt来说,我会说是的,是的。@Benoit:顺便说一句,我不明白标准类型上的运算符不是我要重新定义的。pair没有运算符>>,所以我没有定义任何东西,是吗?我找不到一个引号,上面说不能在标准库类型上重载运算符。@Dennis:因为ADL,在命名空间
std
之外提供运算符是没有用的。我在回答问题中提出的一点:“如果我将我的
操作符>
的声明放入命名空间
std
(这在技术上是非法的),那么代码的编译效果会很好。”你的回答是否意味着我的问题的答案是否定的,我应该把
point
作为一个单独的类?对于Ben Voigt来说,我会说是的,确实如此。@Benoit:顺便说一句,我不明白标准类型上的运算符不是我可以重新定义的。pair没有运算符>>,所以我没有定义任何东西,是吗?我找不到一个引号,上面说不能在标准库类型上重载运算符。@Dennis:因为ADL,在命名空间
std
之外提供运算符是没有用的。我是在回答问题中提出的一点:“如果我将我的
运算符>>
的声明放入命名空间
std
(这在技术上是非法的),那么代码的编译效果将与预期的一样。”您在这里没有专门化
std::pair
。我认为这更多地与模板化代码的解析方式有关,而不是与ADL本身有关。我认为这更多地与模板化代码的解析方式有关,而不是与ADL本身有关。