What I am trying to do is to have a variable-size POD as a Pimpl in my library class:
// header file
class foo {
public:
// ctors, copy, move, dtor, etc.
private:
struct impl; // forward-declared
impl* pimpl; // pointer to private implementation
};
Then define several fixed-size implementations like this:
// .cpp implementation file
struct foo::impl {
uint32_t refs;
uint32_t size;
uint32_t len;
uint32_t data;
};
static_assert( sizeof( typename foo::impl ) == 16, "paranoia" );
namespace { // anonymous
typedef typename foo::impl base;
template <size_t S>
struct block : base {
static_assert( S > 16, "invalid block size" );
static_assert((( S - 1 ) & S ) == 0, "block size must be power of 2" );
uint8_t pad[S - 16];
};
typedef block<64> block64;
typedef block<128> block128;
// ...
}
// foo implementation using the above PODs
GCC versions 4.6 and 4.7 have no issues compiling this with -std=c++0x -Wall -pedantic
, but I am still fuzzy about legality of using private nested type name like that. Wading through my [maybe outdated draft] copy of C++11 standard did not give me any better clues.
If anybody can point me to anything (preferably a section in the standard) that proves this one way or the other (legal or not) I would be eternally grateful.
The implementation you have is not legal: Access to foo::impl
is private, i.e., only the definition of foo
or its members can reference it. In the implementation file you reference the name at namespace scope.
The relevant part of the standard is 11 [class.access] paragraph 1 and paragraph 4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With