See also the discussion on design philosophy in section 1.6.1.
The classes all have names starting with “Pl” , using CamelCase; this contrasts with the C functions that start with “PL_” and use underscores.
The wrapper classes (PlFunctor, PlAtom,
PlTerm), etc. all contain a field C_ that 
contains the wrapped value (functor_t, atom_t, term_t 
respectively). If this wrapped value is needed, it should be accessed 
using the unwrap() or unwrap_as_ptr() methods.
In some cases, it's natural to use a pointer to a wrapper class. For 
those, the function PlUnwrapAsPtr() returns nullptr 
if the pointer is null; otherwise it returns the wrapped value (which 
itself might be some kind of “null” ).
The wrapper classes, which subclass WrappedC<...>, 
all define the following methods and constants:
null). 
Some classes do not have a default constructor because it can lead to 
subtle bugs - instead, they either have a different way of creating the 
object or can use the “null” value for the class.PlAtom, 
the constructor takes an atom_t value).C_ - the wrapped value. This can be used directly when 
calling C functions, for example, if t and a 
are of type PlTerm and PlAtom: PlEx(PL_put_atom(t.unwrap(),a.unwrap())) 
(although it's better to do Plx_put_atom(t.unwrap(),a.unwrap()), 
which does the check).null - the null value (typically 0, but 
code should not rely on this).is_null(), not_null() 
- test for the wrapped value being null.reset() - set the 
wrapped value to nullreset(new_value) - set the wrapped value from the 
wrapped type (e.g., PlTerm::reset(term_t new_value))reset_wrapped(new_value) - set the wrapped value from 
the same type (e.g., PlTerm::reset_wrapped(PlTerm new_value))bool operator is disabled - you should use not_null() 
instead.8The reason: a bool 
conversion causes ambiguity with PlAtom(PlTterm) 
and PlAtom(atom_t).
The method unwrap() can be used to access the C_ 
field, and can be used wherever a atom_t or term_t 
is used. For example, the PL_scan_options() example code can be 
written as follows. Note the use of &callback.unwrap() 
to pass a pointer to the wrapped term_t value.
PREDICATE(mypred, 2)
{ auto options = A2;
  int        quoted = false;
  size_t     length = 10;
  PlTerm_var callback;
  PlCheckFail(PL_scan_options(options, 0, "mypred_options", mypred_options,
                              "ed, &length, &callback.unwrap()));
  callback.record(); // Needed if callback is put in a blob that Prolog doesn't know about.
                     // If it were an atom (OPT_ATOM): register_ref().
  <implement mypred>
}
For functions in SWI-Prolog.h that don't have a C++ 
equivalent in SWI-cpp2.h, PlCheckFail() 
is a convenience function that checks the return code and throws a PlFail 
exception on failure or PlException if there was an 
exception. The enclosing PREDICATE() 
code catches PlFail exceptions and converts them to the foreign_t 
return code for failure. If the failure from the C function was due to 
an exception (e.g., unification failed because of an out-of-memory 
condition), the foreign function caller will detect that situation and 
convert the failure to an exception.
The “getter” methods for PlTerm all throw an 
exception if the term isn't of the expected Prolog type. The “getter” methods 
typically start with “as” , e.g. PlTerm::as_string(). 
There are also other “getter” methods, such as PlTerm::get_float_ex() 
that wrap PL_*() functions.
 “getters” for integers have an additional problem, in 
that C++ doesn't define the sizes of int, long, 
or
size_t. It seems to be impossible to make an overloaded 
method that works for all the various combinations of integer types on 
all compilers, so there are specific methods for int64_t,
uint64_t, size_t.
In some cases,it is possible to overload methods; for example, this 
allows the following code without knowing the exact definition of
size_t:
PREDICATE(p, 1)
{ size_t sz;
  A1.integer(&sz);
     ...
}
It is strongly recommended that you enable conversion checking. 
For example, with GNU C++, use these options (possibly with -Werror):
-Wconversion -Warith-conversion -Wsign-conversion 
-Wfloat-conversion.
There is an additional problem with characters - C promotes them to int 
but C++ doesn't. In general, this shouldn't cause any problems, but care 
must be used with the various getters for integers.