I have 3 classes, Device
, Register
, and WriteOnlyPolicy
, defined as such:
Device
class Device
{
public:
template<class Register>
inline void write(typename Register::value_type value)
{
Register::writeRegister(value, this);
}
protected:
// limit device-specific API calls to this function
virtual void writeDeviceRegister(uint64_t address, uint64_t value) = 0;
};
Register
template<uint64_t ADDRESS, class ValueType, template<class> class AccessPolicy>
struct Register : public AccessPolicy<ValueType>
{
using value_type = ValueType;
using access_policy = AccessPolicy<ValueType>;
static void writeRegister(value_type value, Device* device)
{
access_policy::write(ADDRESS, device, value);
}
}
WriteOnlyPolicy
template<typename value_type>
class WriteOnlyPolicy
{
protected:
static void write(uint64_t ADDRESS, Device* device, value_type value)
{
// convert from a value_type to a uint64_t...
// Shift/mask as needed...
device->writeDeviceRegister(ADDRESS, value);
}
};
Register
and WriteOnlyPolicy
never actually get instantiated in this scheme, but I want the policy to call the protected writeDeviceRegister
function of the Device
class. I don't want that function to be public as I only want to expose the write
function to users of the class, and not the device-specific implementation.
In order to allow that I want Device
to friend Register::access_policy
(which in this case would be the WriteOnlyPolicy
class given as a template argument), but I can't figure out the syntax to friend a dependent typename of a template class. Is this possible?
I thought that putting a friend
declaration in the Device
class such as
template<uint64_t a, class b, template<class> class c>
friend typename Register<a,b,c>::access_policy;
would do the trick, but I get the error
error: expected unqualified-id before ';' token