10

I am learning C++. And my professor uses some code which is something like

using filePath = std::string;
using setOfPaths = std::set<filePath>;
using iterOfSet = setOfPaths::iterator;
using listOfIter = std::list<iterOfSet>;
using iterList = listOfIter::iterator;
using fileName = std::string;
using mapOfFileName = std::map<fileName, listOfIter>;
using iterOfMap = mapOfFileName::iterator;

setOfPaths _setOfPaths;
mapOfFileName _mapOfFileName;
iterOfSet setIter;

I want to know why we are using the using keyword. Why can't we simply write

std::string filepath;

std::set<filepath> setOfPaths;
...
...

What is the benefit of having using keyword?

Radiodef
  • 37,180
  • 14
  • 90
  • 125
tanz
  • 627
  • 1
  • 10
  • 21
  • 6
    Out of curiosity, what was your professor's response to that question? It is, after all, his code, so may as well go to the horse first if it is available. [Several answers here](http://stackoverflow.com/questions/20790932/what-is-the-logic-behind-the-using-keyword-in-c) on the subject of `using` and its various language flavors. – WhozCraig Feb 18 '15 at 03:01
  • @WhozCraig : the horse ?? – Quentin Feb 18 '15 at 03:05
  • 3
    this is really _hard_ to read IMO – Bryan Chen Feb 18 '15 at 03:06
  • 1
    @Quentin never heard of "straight from the horse's mouth"? – user253751 Feb 18 '15 at 03:07
  • 2
    @Quentin an old phrase, "straight from the horses mouth". [see here](http://idioms.thefreedictionary.com/from+the+horse's+mouth). The origins are suspect but I believe it was a wish that one could ask the horse why the race was lost directly rather than listening to the lame excuses of the jockey who, in reality, pull the beast up short to win a few side bets. If only the horse could tell you what *really* happened. – WhozCraig Feb 18 '15 at 03:08
  • I may have heard it once, but didn't recognize it here. Funny expression ! – Quentin Feb 18 '15 at 03:14
  • I had a former boss who once told me that using `using` in such a fashion was abnormal. I have since come to the conclusion that my boss was wrong and in fact many people simply need to learn more about the language. This is perfectly acceptable to me. – inetknght Feb 18 '15 at 03:56

1 Answers1

16

The using keyword is used to define type aliases. The reasons your professor is using it are:

  • readability
  • being more descriptive
  • avoid unnecessary typename

Readability and descriptiveness

You can use type aliases to semantically (and only that) restrict a specific type, making the name more descriptive for the specific use.

An example is:

using fileName = std::string;

The fileName alias is used to describe a file name string, not just any string. This makes for readable function signatures too.

I feel like I have to iterate this again: it's simply an alias. Any function taking fileName as an argument will work just fine with any std::string argument.

Unnecessary typenames

Some may seem unnecessary, like:

using setOfPaths = std::set<filePath>;

but in some cases they can be actually used to avoid having to specify typename in situations like:

template<typename Type>
struct something {
    using something_iter = typename std::set<Type>::iterator;
};

with:

template<typename Container>
using itertype = typename Container::iterator;

template<typename Type>
struct something {
    using something_iter = itertype<std::set<Type>>;
}; 

By moving typename in a specific alias we can reuse itertype in multiple other occasions effectively avoiding typename.

A note on typedef

There's another way to define type aliases: typedef. That keyword is inherited from C and does not allow for templated aliases, like:

template<typename Type>
using vec = std::vector<Type>;

A note on type safety

This is not actually any more type safe than not using aliases at all. Again, fileName and std::string are exactly the same type. You can use both interchangeably.

A possible next step would be to define a specific fileName class/struct type with its own specific invariants.

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • I was just about to answer this similarly. It's also much more convenient to use something with a short name, much like `typedef`. – erip Feb 18 '15 at 03:03
  • 1
    The first example for readability in this answer is dreadful. `std::string const& fileName` or similarwould be *amply* descriptive by id. `using MapIDToFileName = std::map;` hopefully demonstrates the point better. Nice answer regardless. – WhozCraig Feb 18 '15 at 03:13
  • 1
    @Praetorian : I'm pretty sure it is. Or is it only when the preceding argument is a template parameter ? – Quentin Feb 18 '15 at 03:15
  • One of the nice things about typedef or using is that you can easily change the underlying type across the board in your code without having to search and replace - provided that the underlying types are compatible of course. So even if there's no increase in readability, as @WhozCraig indicates with std::string, there is the potential convenience of changing the underlying type at a later date, and not accidentally replacing the type on something that really was supposed to remain a std::string. – Arunas Feb 18 '15 at 03:18
  • @tanz, if you like this answer, then I'm sure would appreciate you selecting it as _the_ answer. – Arunas Feb 18 '15 at 03:19
  • Already did. Actually I can only accept after 5-10 mins. I tried before but SO told me to wait for some time before I can accept it. – tanz Feb 18 '15 at 03:21
  • @Praetorian : nope, you're right. I must be mixing it up with something else. – Quentin Feb 18 '15 at 03:23