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?
The header file contains only declarations, and is included by the . c file for the module. Put only structure type declarations, function prototypes, and global variable extern declarations, in the . h file; put the function definitions and global variable definitions and initializations in the .
You request to use a header file in your program by including it with the C preprocessing directive “#include”.
Usually, every program contains “#” at the top, which is a preprocessor directive that includes files or definitions.
However this has the drawback, that I need to restate the alias in the source file:
That is incorrect. You need only make it public
then specify the proper scope, so you'd call it Bar::FooTable
outside of the scope of Bar
(which includes return types, unless trailing!):
Bar::FooTable Bar::create_foo()
{ /* ... */ }
or
auto Bar::create_foo() -> FooTable
{ /* ... */ }
(Just FooTable
is fine within the definition, as it's a member!)
Your approach is fine, though I'd put everything in a namespace too. Then it doesn't really matter whether your alias is in the class or not: it's still self-contained within your own code. It becomes purely a matter of style, with little to no impact on anyone else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With