Design patterns: use of friend classes to encapsulate the functions of private members in C ++: good practices or abuse?

Then I realized that it is possible to avoid putting private functions in the headers by doing something like this:

// In the pred_list.h file:
PredicateList class
{
int somePrivateField;
friend class PredicateList_HelperFunctions;
public:
bool match ();
}

// In the pred_list.cpp file:
class PredicateList_HelperFunctions
{
static bool fullMatch (PredicateList & p)
{
returns p.somePrivateField == 5; // or whatever
}
}

bool PredicateList :: match ()
{
return PredicateList_HelperFunctions :: fullMatch (* this);
}

The private function is never declared in the header, and consumers in the class that import the header do not need to know it exists. This is necessary if the auxiliary function is a template (the alternative is to put the complete code in the header), which is how I "discovered" this. Another good advantage of not having to recompile all the files that include the header if you add / remove / modify a private member function. All private functions are in the .cpp file.

So…

  1. Is this a known design pattern for which there is a name?
  2. For me (coming from a Java / C # background and learning C ++ in my own time), this seems like a very good thing, since the header is defining an interface, while .cpp is defining an implementation (and the time of improved compilation is a good bonus). However, it also smells like you are abusing a language function that is not meant to be used that way. Then what is? Is this something you would like to see in a professional C ++ project?
  3. A consumer could define their own class PredicateList_HelperFunctions, and allows them to access private fields. While I do not see this as a huge problem (if you really wanted in those private fields, you could do some casting), would you perhaps encourage consumers to use it that way?
  4. Any other trap I'm not thinking about?

EDIT: I am aware of Pimpl, which is a much more robust way to hide the implementation on the edge of the library. This is more for use with internal classes, where Pimpl could cause performance problems or not work because the class should be treated as a value.