Skip to main content Skip to navigation

renaming first and second in C++

When using an interator for a map class the use of first and second to get at the key and value can be confusing.

If a class is defined which inherits from the std::map then the following macros define new versions of the pair and iterator classes which provide methods for accessing the key and data by name.

The following creates a pair class which is used in the new C++11 for (x : y) loops

#define ADD_MAPPAIR(_first,_second) \
struct Pair { \
pair<const key_type,mapped_type> & _p; \
Pair(pair<const key_type,mapped_type> & _a) : _p(_a){}; \
key_type _first () {return _p.first;}; \
mapped_type & _second () {return _p.second;}; \
}

And the following creates an Iterator class for conventional interation

#define ADD_ITER(_first,_second) \
struct Iterator : public iterator { \
Iterator() {}; \
Iterator(const iterator & _a) : iterator(_a){}; \
key_type _first() { return (*this)->first;}; \
mapped_type & _second() { return (*this)->second;}; \
}

The following shows both being used in a simple map class

struct demoMap : public map<int,double>
{
ADD_ITER(theIterKey,theIterValue);
ADD_MAPPAIR(theKey,theValue);
};

The following is an instance of the class where the new 'Pair' class is used to access the ket and data usig the new accessor functions theInt() and theDouble() as defined in the macro, rather than first and second. tehInt and theDouble can of course be renamed to be anything suitable.

demoMap dataMap;
dataMap.emplace(1,4.0);
dataMap.emplace(2,7.0);
for (demoMap::Pair i : dataMap)
{
int x = i.theKey();
i.theValue() = 22 + x;
}

And then the following uses the new Iterator (rather than iterator, upper rather than lower case) class to iterate through the values in the conventional way

for (demoMap::Iterator i = dataMap.begin();i != dataMap.end();i++)
{
int x = i.theIterKey();
double y = i.theIterValue();
cout << y;
}