static initialization in header only library?

Hi,
I want to write a logging library and so im currently in the process of figuring out how best to go about it.
So far im imagining doing something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Logger : public std::stringstream
{
  Logger()
  ~Logger() //writes stringstream::str() to each stream in m_streamRefs

  static void AddStream(std::ostream& stream); //adds stream to m_streamRefs

  private:
  static std::vector<std::reference_wrapper<std::ostream>> m_streamRefs;
};

//usage:
Logger::AddStream( std::cout );
Logger::AddStream( std::cerr );

Logger{} << "sfjsdlfjdslj\n";

//ideally i will have macros that can be turned on / off
DEBUG_LOG << "sdfjsldjf\n";


The thing is that i would like to keep it a header-only library (because i want to make logging macros that you can then turn on / off at compile time & not have to worry about telling your build system when / when not to link with the library).

The problem with this is that the m_streamRefs member need to be static and a static variable has to be initialized in a translation unit but since i want it to be a header-only library i dont have a translation unit to initialize it in.
And so when i compile it i get an undefined reference to m_streamRefs error.

Is there anything i can do about this? is there some way i can make the "includer" initialize the static variable (without having to manually type it) but at the same time avoid redefinition errors ?
Last edited on
Inline variables! You'll need a compiler with the appropriate C++17 support, but otherwise you can add the line
inline std::vector<std::reference_wrapper<std::ostream>> Logger::m_streamRefs;
to your header. This will create multiple definitions across translation units, but they will all share the same address across those units. Neat, no?

Otherwise, if you can't use C++17, you can probably do something with an inline static member function that returns a reference to a (local) static variable.

-Albatross
Thanks alot guys
Topic archived. No new replies allowed.