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.)
0 comments