我应该在哪里定义operator >>用于我对std :: pair的专门化?

Arm*_*yan 15 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 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命名空间中模板的特化之外,有没有办法解决这个问题?

提前致谢

Ben*_*igt 11

禁止添加operator>>in 的重载namespace std,但有时允许添加模板特化.

但是,此处没有用户定义的类型,标准类型的运算符不是您重新定义的.专业化operator>>(istream&, pair<mytype, int>)是合理的.


部分[namespace.std](第n3290的17.6.4.2.1)说:

如果C++程序将声明或定义添加到命名空间std或命名空间中的命名空间std,则除非另有说明,否则C++程序的行为是未定义的.只有当声明取决于用户定义的类型并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std.

(强调我的)

  • @Dennis:由于ADL,在名称空间`std`之外提供运算符是没用的.我正在解决关于"如果我将我的`运算符>>的声明放入命名空间`std`(这在技术上是非法的)的问题中提出的问题,代码编译得很好." (2认同)