Consider the following code spread out along 3 files:
// secret.h
#pragma once
class Secret { /* ... */ };
// foo.h
#pragma once
#include "secret.h"
template <typename T>
class Foo {
public:
// Other members ...
void bar();
};
/* Definition is included inside 'foo.h' because Foo is a template class. */
template <typename T> void Foo<T>::bar() {
Secret s;
/* Perform stuff that depend on 'secret.h' ... */
}
// main.cpp
#include "foo.h"
int main() {
Foo<int> foo;
Secret secret; // <--- This shouldn't be allowed, but it is!
return 0;
}
So my issue is that I want to hide Secret from the user of Foo unless they explicitly use #include "secret.h". Normally, this would be done by including secret.h in foo.cpp. However, this isn’t possible because Foo is a template class and I cannot separate its definition from its declaration. Explicit template instantiation is not an option.
Ultimately, I want to know if this is possible in some way other than Explicit template instantiation, and if so, how? Thanks!
So thanks to @Mooing Duck’s hint, I think I got the answer. They way I’m considering solving this by creating a new class that acts as a thin wrapper for Secret that does not rely on a template parameter. This class would friend Foo and provide protected access to Secret, thus allowing Foo to access Secret without exposing Secret to the public user through inclusion of
"foo.h".I will update this answer with the actual code snippet once I write and compile it and make sure that it works.