Hacker News new | past | comments | ask | show | jobs | submit login

C++ could solve this without badges, if it didn't have a very tiny, silly misfeature.

The misfeature is this: a class A can only declare a specific member function of class B as a friend, if that B member function is public!


The idea here is that Device has a static member function called Device::registrationHelper. That specific function (not the entire Device class) is declared a friend to VFS, and so that function can call VFS::registerDevice.

[Edit: this doesn't quite match the Badge solution, though. If this worked, it would have the problem that the registrationHelper has access to all of VFS, which is almost as bad as the entire Device class being a friend of VFS. That is one of the problems which motivate Badge. Nice try, though! The C++ restriction is probably worth fixing anyway. What the C++ friendship mechanism really needs here is to be able to say that a specific member function in B is allowed to access a specific member of A.]

  class Device;

  class VFS;

  class Device {
  public:  // we want this private!
     static void registrationHelper(VFS &v, Device &d);
     void registerWith(VFS &vfs) { registrationHelper(vfs, *this); }

  class VFS {
     void registerDevice(const Device &);
     friend void Device::registrationHelper(VFS &, Device &);

  void Device::registrationHelper(VFS &v, Device &d)
But we are forced to make Device::registrationHelper public, which defeats the purpose: anyone can call it and use it is a utility to register devices with VFSs.

If we make Device::registrationHelper private to prevent this, then the "friend void Device::registrationHelper" declaration in VFS fails.

This is an oversight; the privacy of the Device::registrationHelper identifier means that the VFS class is not even allowed to mention its name for the sake of declaring it a friend.

That should be fixed in C++. Declaring a function a friend shouldn't require it to be accessible; we are not lifting its address or calling it; we are just saying that it can call us. Allowing a function to call us is not a form of access to that function, yet is being prevented by access specifiers.

Your solution is similar to mine and you might find it helpful:


Registration is open for Startup School 2019. Classes start July 22nd.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact