Is it possible to downcast between std::atomic_ref<T>
and std::atomic_ref<U>
where U
is a subclass of T
?
I tried the following code which didn't work.
template<typename T>
std::atomic_ref<T> World::getComponentByID(componentInstanceId uuid) const {
static componentTypeId key = stringHash(typeid(T).name());
return components.at(uuid);
}
The template parameter T
was position (a subclass of Component
). components
is a map of componentInstanceId
s to Component
s .
error C2440: 'return': cannot convert from 'const std::atomic_ref<Component>' to 'std::atomic_ref<Position>
CodePudding user response:
Usage of atomic_ref
this way does not make sense. (Even in lock_free
cases that make sense in assembly language, the ISO C standard doesn't expose that functionality.)
As @Igor Tandetnik pointed out, "No subobject of an object referenced by an atomic_ref object may be concurrently referenced by any other atomic_ref object."
One of reasons this rule exists is that for non-lock-free atomic_ref
it implements pool of mutexes, so having sub-object with different pointer value will get you into a different mutex for a subobject, or even a mutex from a different pool, or it may happen that sub-object is lock-free, but the bigger object is lock-based.
Additionally, possible pointer adjustments may defeat alignment, and it is mandatory for value referenced by atomic_ref
to respect atomic_ref<T>::required_alignment
.
atomic_ref
is not a general purpose facility. Perhaps you just need to protect your objects with std::mutex
or std::shared_mutex
instead.