The pointer-related Interlocked functions
all operate on void*
.
In practice, though, you are operating on typed
pointers.
Here are some helper functions to save you a bunch of typing.
template<typename T, typename U> T* InterlockedExchangePointerT( T* volatile *target, U value) { return reinterpret_cast<T*>(InterlockedExchangePointer( reinterpret_cast<void* volatile*>(target), static_cast<T*>(value))); } // Repeat for InterlockedExchangePointerAcquire and // InterlockedExchangePointerNoFence. template<typename T, typename U, typename V> T* InterlockedCompareExchangePointerT( T* volatile *target, U exchange, V compare) { return reinterpret_cast<T*>(InterlockedCompareExchangePointer( reinterpret_cast<void* volatile*>(target), static_cast<T*>(exchange), static_cast<T*>(compare))); } // Repeat for InterlockedCompareExchangePointerAcquire, // InterlockedCompareExchangePointerRelease, and // InterlockedCompareExchangePointerNoFence.
The naïve versions of these functions would be
template<typename T, typename U> T* InterlockedExchangePointerT( T* volatile *target, T* value) { return reinterpret_cast<T*>(InterlockedExchangePointer( reinterpret_cast<void* volatile*>(target), value)); } template<typename T, typename U, typename V> T* InterlockedCompareExchangePointerT( T* volatile *target, T* exchange, T* compare) { return reinterpret_cast<T*>(InterlockedCompareExchangePointer( reinterpret_cast<void* volatile*>(target), exchange, compare)); }
but those simpler versions fail on things like
class Base { ... }; class Derived : public Base { ... }; extern Base* b; Derived* d = new Derived(); if (InterlockedCompareExchange(&p, d, nullptr)) ...
because the compiler wouldn't be able to choose a
value for T
.
From the first paramter, it would infer that
T = Base
;
from the second parameter,
it would infer that
T = Derived
;
and from the third parameter,
it would give up because it can't figure out what
value of T
would result in
T*
being the same as
std::nullptr_t
.
(You can guess how I discovered these limitations of the naïve versions.)