【问题标题】:Where should I define operator >> for my specialization of std::pair?我应该在哪里为我的 std::pair 特化定义运算符 >>?
【发布时间】:2011-07-30 18:14:28
【问题描述】:

考虑以下程序:

#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
}

这无法编译,因为一旦 ADL 在命名空间 std 中找到运算符 >>,它就不再考虑全局范围,无论在 std 中找到的运算符是否是可行的候选者。这是相当不方便的。如果我将运算符 >> 的声明放入命名空间 std(这在技术上是非法的),则代码可以按预期编译。除了将point 设为我自己的类而不是将其定义为 std 命名空间中模板的特化之外,还有什么方法可以解决此问题?

提前致谢

【问题讨论】:

  • 您在这里没有专门针对std::pair。我认为这与模板化代码的解析方式有关,而不是与 ADL 本身有关。

标签: c++ stl template-specialization argument-dependent-lookup


【解决方案1】:

禁止在namespace std 中添加operator&gt;&gt; 的重载,但有时允许添加模板特化。

但是,这里没有用户定义的类型,标准类型上的运算符也不是你可以重新定义的。专业化operator&gt;&gt;(istream&amp;, pair&lt;mytype, int&gt;) 是合理的。


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

除非另有说明,否则如果 C++ 程序将声明或定义添加到命名空间 std 或命名空间 std 内的命名空间,则其行为未定义。 只有当声明依赖于用户定义的类型时,程序才能将任何标准库模板的模板特化添加到命名空间 std,并且特化满足原始模板的标准库要求并且不明确禁止。

(强调我的)

【讨论】:

  • 您的回答是否暗示我的问题的答案是,我应该将point 设为一个单独的班级?
  • 代表 Ben Voigt,我会说是的,确实如此。
  • @Benoit:顺便说一句,我不明白标准类型的运算符不是我的_re_define。对没有运算符>>,所以我没有_re_defining任何东西,是吗?
  • 我找不到说您不能在标准库类型上重载运算符的引用。
  • @Dennis:由于 ADL,在命名空间 std 之外提供运算符是没有用的。我正在解决问题中提出的问题,即“如果我将 operator &gt;&gt; 的声明放入命名空间 std(这在技术上是非法的),则代码可以按预期编译。”
猜你喜欢
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多