Domanda

I want to know if there is a C++ function, or at least a convention for doing this:

int a = 5, b = 5, *pa = &a, *pb = &b; //These are example values if the if statement were true

if( ( pa == NULL && pb == NULL ) || ( pa != NULL && pb != NULL && *pa == *pb ) ) //Do stuff

I can improve on this a little by doing: !( ( pa == NULL ) ^ ( pb == NULL ) ) && ( !pa || *pa == *pb ) But it just seems like there should be a cleaner way of doing this.

È stato utile?

Soluzione

I would probably write:

if (pa == pb || (pa && pb && *pa == *pb))

You could get the benefit of that Perl syntax with a function template backed by a helper class that implements comparison:

template <typename T>
struct Maybe {
    T *ptr
    explicit Maybe(T *ptr) : ptr(ptr) {}
    bool operator==(const Maybe &other) const {
        return (ptr == other.ptr) || (ptr && other.ptr && *ptr == *other.ptr);
        // or whatever other answer to this question you like
    }
    bool operator!=(const Maybe &other) const {
        return !(*this == other);
    }
};

// could make it work for smart pointer types too,
// but this is simple
template <typename T>
Maybe<T> maybe(T *ptr) { return Maybe<T>(ptr); }

if (maybe(pa) == maybe(pb)) ...

Obviously that's only worth if it you do this in a lot of different places. And to replace this one use of the Perl syntax, you could just as well have a function template that takes two pointers and returns the result...

Altri suggerimenti

One possible simplification is:

if ( ( pa == pb ) || ( pa != NULL && pb != NULL && *pa == *pb ) ) //Do stuff

This works because the first clause handles two cases: (i) both pa and pb are NULL or (ii) pa and pb are not NULL, but they are equal and therefore point to the same value, in which case *pa == *pb.

The predicate "either both pointers are null, or both pointers are non-null and the pointees are equal", could be written like this:

return pa == NULL ? pb == NULL : (pb != NULL && *pa == *pb);

if (pa == pb || pa && pb && *pa == *pb) // Do stuff

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top