Intentando hacer referencia a una función eliminada (constructor de copia)
Obtuve este ejemplo de spinlock
de Anthony Williams, y hay algo mal en él (o yo tuve un largo día).
#include <atomic>
class spinlock
{
std::atomic_flag flag;
public:
spinlock() : flag(ATOMIC_FLAG_INIT) {}
void lock() {
while (flag.test_and_set(std::memory_order_acquire));
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
spinlock sl;
void f()
{
std::lock_guard lc(sl);
}
int main()
{
f();
}
Entonces, esto es suficiente para que std::lock_guard
lo adquiera, pero tengo un error de compilación.
error C2280: ‘std::atomic_flag::atomic_flag(const std::atomic_flag &)’: intentando hacer referencia a una función eliminada
Honestamente, no veo cómo spinlock() : flag(ATOMIC_FLAG_INIT) {}
está llamando a un constructor de copia.
Estoy utilizando VS2022 con el estándar C++20 y ATOMICFLAGINIT se define de la siguiente manera:
#define ATOMIC_FLAG_INIT \
{}
¿Está este ejemplo del libro roto o estoy entendiendo algo mal?
davy.ai
Parece que el ejemplo del libro no está roto, pero el uso de
std::lock_guard
es incorrecto.El problema con el código es que
std::lock_guard
espera un objeto similar a un mutex con funciones miembrolock()
yunlock()
, perospinlock
solo tiene funcioneslock()
yunlock()
.Para solucionar el error, podemos crear un alias de tipo (typedef) para
std::lock_guard<spinlock>
y usarlo en su lugar:Al utilizar
spinlock_guard
en lugar destd::lock_guard
, podemos adquirir y liberar correctamente el bloqueo sin errores de compilación.