Please excuse me if this is asked elsewhere (and provide a link!). I wasn't able to find an exact duplicate.
Not sure if I'm even phrasing the Q correctly.
As a minimal example:
#include <cstdint>
#include <vector>
class Priv {
protected:
// All members of Priv are protected and should not be accessed directly.
using Typ = uint16_t;
// (In reality, Typ is defined based on various macro definitions.)
// ...
// However, I would like to give access to classes I specifically befriend.
// All instantiations of Public should be permitted, regardless of T.
template <typename T> friend struct Public;
};
// Default arguments in class Public's template parameter list should be able to
// access protected members of Priv because Public has been friend-zone'd, right?
template <typename T = Priv::Typ>
struct Public: std::vector<T> {
inline Public(): std::vector<T>() {}
};
int main() {
Public pub; // should default to Public<Priv::Typ>
}
But unfortunately, I seem to be declaring the friend incorrectly:
<source>:17:30: error: 'using Typ = uint16_t' is protected within this context
17 | template <typename T = Priv::Typ>
|
Can someone point out my mistake?
The default template argument is outside the class scope, not inside it. It makes
Public<>to be equivalent toPublic<Priv::Typ>where clearly the argument is used in the context of the user, not the class. So it shouldn't be possible to use aprotectedmember in this context.You can only use the
private/protectedmembers of the class inside thefriend's scope. So if you want the user of the class template to be able to specify the type either implicitly or explicitly while still havingTypmarkedprotected, then you need to do a translation toTypsomehow inside the class scope. For example:But it is not clear to me what the intent for doing this is.