I've a single header requirement on a code, which means there should be no splitting of declarations and definitions into separate header and source files. I've implemented it properly and it works as intended for my use case, where this header file was meant to be included in only single source file.
Now when it comes to it's use in multiple source files(where more than one .cpp includes it), it will fail with linker error along the lines that some variables are being redeclared. That is because I've the code like -
#ifndef HEADER_HPP
#define HEADER_HPP
....
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
void doSomething(){
[uses if(R_coutbuf) and others]
}
....
#endif HEADER_HPP
Now the best solution would be to declare those vars in header file and define/assign them in single cpp file, but as I said I want to be able to do this with a single header file. Which brings to the problem that if multiple source files will include it, there will be redeclarations.
So far I'm not sure how should I be able to do this but I've two ideas -
#ifdef DEFINE_VARIABLES
#define EXTERN /* nothing */
#else
#define EXTERN extern int
#endif /* DEFINE_VARIABLES */
EXTERN global_variable = something;
I'm not so sure about it, would this even work?
And the second way I thought about is to put it in an anonymous namespace, am trying this one and so far its building successfully -
#ifndef HEADER_HPP
#define HEADER_HPP
....
namespace R {
namespace {
std::streambuf const *R_coutbuf = std::cout.rdbuf();
std::streambuf const *R_cerrbuf = std::cerr.rdbuf();
std::streambuf const *R_clogbuf = std::clog.rdbuf();
}
void doSomething(){
[uses if(R_coutbuf) and others]
}
}
....
#endif HEADER_HPP
Is there any other way I could achieve this? Are there any problems with either of the ways I described above.
You could make your variable a local static variable in a function:
inline std::streambuf const*& R_coutbuf() {
static std::streambuf const* b = std::cout.rdbuf();
return b;
}