Итак, подумав некоторое время, это лучшее решение, которое я смог найти:
class C {
int m_i { 0 };
void assignFrom(const volatile C& src, const bool volatileSrc = true, const bool volatileSelf = true) volatile {
auto& nqSrc = volatileSrc ? src : const_cast<const C&>(src);
auto& self = volatileSelf ? *this : *const_cast<C*>(this);
self.m_i = nqSrc.m_i;
}
public:
void operator=(const C& src) volatile {
// non-volatile to volatile assignment
assignFrom(src, false);
}
C& operator=(const volatile C& src) {
// volatile to non-volatile assignment
assignFrom(src, true, false);
return *this;
}
C& operator=(const C& src) {
// non-volatile to non-volatile assignment
assignFrom(src, false, false);
return *this;
}
};
Я проверил его, и, похоже, он работает нормально.