1

Not sure this is possible, but if so, how do you use an atomic enum class for a switch statement in C++11? For example,

#include <atomic>
#include <iostream>

enum class A {RED, FRUIT, APPLE};

int main(){
    std::atomic<A> myAtomicEnum;
    myAtomicEnum = A::RED;
    switch (myAtomicEnum){
        case A::RED:
            std::cout << "A::RED \n";
            break;
        default:
            break;
    }
    return 0;
}

gives a compiler error

error: multiple conversions from switch condition type
      'std::atomic<A>' to an integral or enumeration type
    switch (myAtomicEnum){

A different question using an enum class (not atomic) forced a conversion to arithmetic type using a unary +, but you can't pass an std::atomic<A> to the unary +. I don't receive any errors using a non-atomic enum class and not using a unary +, e.g.

#include <iostream>

enum class A {RED, FRUIT, APPLE};

int main(){
    A myEnum = A::RED;
    switch (myEnum){
        case A::RED:
            std::cout << "A::RED \n";
            break;
        default:
            break;
    }
    return 0;
}

which outputs A::RED as expected.

The context of the problem is that I have a class with a member that may be read/written to by multiple threads and a switch statement using that member. I have a workaround using mutex-es so that I have well-defined behavior but would like to use atomic if possible.

MikeM
  • 13
  • 2
  • 1
    Does not seem wrong to me. Perhaps specify platform, compiler and command line and full error message verbatim. – Öö Tiib Oct 11 '22 at 13:47

1 Answers1

1

In C++ 11, you may explicitly cast atomic type variable to enum type, this will call std::atomic<T>::operator T() casting operator of the object:

switch ((A)myAtomicEnum){
    case A::RED:
        ...

Btw, starting from C++ 14 this explicit cast is not needed, and cast to switch type will be done implicitly (cppreference.com, Implicit conversions page)

Renat
  • 7,718
  • 2
  • 20
  • 34
  • 1
    Thank you! Accepted as the answer, I did not realize I could do this. For the sake of searching for casts, I am partial to `switch(static_cast(myAtomicEnum))` even though it is more verbose. – MikeM Oct 11 '22 at 14:52
  • 1
    @MikeM: I'd have done `myAtomicEnum.load()` to get a `T` from `atomic`. https://godbolt.org/z/37T5hfrjM . (I can't reproduce the error on Godbolt even with old gcc `-std=c++11`; their `` header is new enough I guess?) – Peter Cordes Oct 11 '22 at 21:16
  • Turned out gcc with `-std=c++11` makes implicit cast, but clang with `-std=c++11` and no explicit cast shows compilation error – Renat Oct 11 '22 at 22:43