For my project I am using some pretty convoluted data structures, e.g.
std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>
for which I would like to declare type aliases for readability. The code on which I built my project on already did this by putting using
statements globally in the header files:
// bar.h
#ifndef BAR_H
#define BAR_H
#include <unordered_map>
#include <list>
#include <memory>
#include "foo.h"
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
class Bar {
FooTable create_foo();
};
#endif
Since my C++ knowledge was a little rusty, I just adopted this style -- but now I read that using using
in that way can be problematic, since it forces this alias on everything that includes this header.
Despite a good amount of googling, I could not find a concrete answer on how to handle this properly, only lots of statements on what not to do. So, I just put the using inside the class:
// bar.h
#ifndef BAR_H
#define BAR_H
#include <unordered_map>
#include <list>
#include <memory>
#include "foo.h"
class Bar {
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
FooTable create_foo();
};
#endif
However this has the drawback, that I need to restate the alias in the source file:
// bar.cpp
#include "bar.h"
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
FooTable Bar::create_foo()
{
...
}
While this seems to work, I am not sure whether this is safe... and my gut tells me it is kind of ugly. So before I rewrite my whole project like this I thought I'd ask: Is a there a better/more elegant/safer way to do this? Or should I just refrain from using type aliases in header files completely?
typedef
. – LaoFooTable
is in theBar
class. So you need to specify that, as inBar::FooTable Bar::create_foo()
– TuberculosisBar::FooTable
instead. – Sumusing FooTable = ...
within the classBar
. When definingBar::create_foo()
in a separate source file, I would specify its return value asBar::FooTable
. But I'm an advocate in ensuring names have the most restrictive scope possible - and you've provided no justification to suggest thatFooTable
makes sense outsideBar
. Other folks may advocate something different. – Melodious