Question

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!

Was it helpful?

Solution 2

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.

OTHER TIPS

That is not possible with all those conditions which you mentioned, because writing #include "foo.h" means you also implictly write #include "secret.h" (means, all it contents).

You can use namespace such as details to limit the visibility of the name of the class:

// secret.h
#pragma once

namespace details
{
   class Secret { /* ... */ };
}

And then write details::Secret wherever you use it.

DO NOT write using namespace details;, NOT even using details::Secret;.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top