Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I define operator >> for my specialization of std::pair?

Consider the following program:

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

This fails to compile because as soon as ADL finds operator >> in namespace std it doesn't consider the global scope any more regardless of whether the operator found in std was a viable candidate or not. This is rather inconvenient. If I place the declaration of my operator >> into namespace std (which is technically illegal) the code compiles well as expected. Is there any way to resolve this issue other than make point my own class rather than typedefing it as a specialization of a template in std namespace?

Thanks in advance

like image 309
Armen Tsirunyan Avatar asked Jul 30 '11 18:07

Armen Tsirunyan


People also ask

How to define std:: pair?

std::pair is a class template that provides a way to store two heterogeneous objects as a single unit. A pair is a specific case of a std::tuple with two elements. If neither T1 nor T2 is a possibly cv-qualified class type with non-trivial destructor, or array thereof, the destructor of pair is trivial.

How do you initialize a pair in C++?

Another way to initialize a pair is by using the make_pair() function. g2 = make_pair(1, 'a'); Another valid syntax to declare pair is: g2 = {1, 'a'};

Is std :: pair a struct?

A std::pair is a struct.


1 Answers

Adding an overload of operator>> in namespace std is forbidden, but adding a template specialization is sometimes allowed.

However, there are no user-defined types here, and the operators on standard types are not yours to redefine. Specializing operator>>(istream&, pair<mytype, int>) would be reasonable.


section [namespace.std] (section 17.6.4.2.1 of n3290) says

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

(emphasis mine)

like image 95
Ben Voigt Avatar answered Sep 27 '22 22:09

Ben Voigt