Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Re)named std::pair members

Instead of writing town->first I would like to write town->name. Inline named accessors (Renaming first and second of a map iterator and Named std::pair members) are the best solutions I have found so far. My problem with named accessors is the loss of type safety: pair<int,double> may refer to struct { int index; double value; } or to struct { int population; double avg_temp; }. Can anyone propose a simple approach, perhaps something similar to traits?

I often want to return a pair or a tuple from a function and it is quite tiring to introduce a new type like struct city { string name; int zipcode; } and its ctor every time. I am thrilled to learn about boost and C++0x but I need a pure C++03 solution without boost.

Update

Re andrewdski's question: yes, a (hypothetical) syntax like pair<int=index, double=value> which would create a distinct type from pair<int=population, double=avg_temp> would meet your requirement. I do not even mind having to implement a custom pair/tuple template class ONCE and just passing a 'name traits' template argument to it approprietly when I need a new type. I have no idea how that 'name traits' would look like. Maybe it's impossible.

like image 517
Ali Avatar asked May 21 '11 19:05

Ali


People also ask

Is std :: pair contiguous?

std::pair is a struct, the standard says the compiler determines the layout though the order must be maintained, so in the instance of std::pair<char,char> your compiler may decide to place 3-byte padding after each char for optimal alignment, so no you can't assume contiguous memory layout - end of story.

How do you initialize a new pair?

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'};

What is std :: pair in C++?

> struct 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.

Can we make pair of pair in C++?

C++ pair is a type that is specified under the utility> header and is used to connect two pair values. The pair's values can be of separate or identical types. To view the values in a pair independently, the class has the member functions first() and second().


2 Answers

I don't see how you can possibly do better than

struct city { string name; int zipcode; }; 

There's nothing non-essential there. You need the types of the two members, your whole question is predicated around giving names to the two members, and you want it to be a unique type.

You do know about aggregate initialization syntax, right? You don't need a constructor or destructor, the compiler-provided ones are just fine.

Example: http://ideone.com/IPCuw


Type safety requires that you introduce new types, otherwise pair<string, int> is ambiguous between (name, zipcode) and (population, temp).

In C++03, returning a new tuple requires either:

city retval = { "name", zipcode }; return retval; 

or writing a convenience constructor:

city::city( std::string newName, int newZip ) : name(newName), zipcode(newZip) {} 

to get

return city("name", zipcode); 

With C++0x, however, you will be allowed to write

return { "name", zipcode }; 

and no user-defined constructor is necessary.

like image 118
Ben Voigt Avatar answered Sep 21 '22 17:09

Ben Voigt


I guess elaborating on

struct City : public std::pair<string, int> {   string& name() { return first; }   const string& name() const { return first; }   int& zip() { return second; }   int zip() const { return second; } }; 

is the closest you get to what youre looking for, althrough struct City { string name; int zipcode; } seems perfectly fine.

like image 45
Viktor Sehr Avatar answered Sep 24 '22 17:09

Viktor Sehr