Где я должен определить operator >> для моей специализации std :: pair? - PullRequest
15 голосов
/ 30 июля 2011

Рассмотрим следующую программу:

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

Заранее спасибо

1 Ответ

11 голосов
/ 30 июля 2011

Добавление перегрузки operator>> в namespace std запрещено, но иногда допускается добавление специализации шаблона.

Однако здесь нет пользовательских типов, и операторы стандартных типов не могут быть переопределены вами. Специализация operator>>(istream&, pair<mytype, int>) была бы разумной.


раздел [namespace.std] (раздел 17.6.4.2.1 из n3290) говорит

Поведение программы на C ++ не определено, если она добавляет объявления или определения в пространство имен std или в пространство имен в пространстве имен std, если не указано иное. Программа может добавить специализацию шаблона для любого шаблона стандартной библиотеки в пространство имен std, только если объявление зависит от пользовательского типа и специализация соответствует требованиям стандартной библиотеки для исходного шаблона и не является явно Запрещенный.

(акцент мой)

...