C / C++ NULL takes up space, as does python None . If you need something that takes up space, then using  would not be appropriate.
C / C++ NULL is a valid member of a pointer class. You can store it in a single array of pointer type -- and it often is stored that way. For example if you create a common two-level array, like int** for a pointer to an array of pointers to int, then it would be common to set the unused slots to NULL, and there are no class problems in doing that.
python None is a different class. If you have an object which is expected to be uniform data type, then it cannot have None stored in it.
MATLAB's NaN exists in single precision and double precision, and those are full members of those classes - the IEEE 754 standard defines specific bit patterns for NaN, just like it defines specific bit patterns for infinity. So NaN is suitable for use in a homogenous single or double array situation, and would still be able to test for special value within that class. Contrawise, NaN cannot be used in a homogenous uint8 array or any other class other than single or double.
logical values are not any numeric class, but they silently convert to numeric in many situations. So [1, 2, false, 4] would work, but it would convert to [1, 2, 0, 4] and you would then lose being able to test each entry for special value.
If your purpose is to signal "no value" in a context where it is expected that the results will be assigned to a variable, then using  would be more MATLAB-y. If you need the value to take up space, then use NaN if regular values would be single or double.
In some cases it makes the most sense to return a logical vector of success / failure. An example of this is ismember(), where the first output is success/failure and the second output is the index location.