Por que uma variável enum é um rvalue aqui?

12

Exemplo:

typedef enum Color
{
    RED,
    GREEN,
    BLUE
} Color;

void func(unsigned int& num)
{
    num++;
}

int main()
{
    Color clr = RED;
    func(clr);
    return 0;
}

Eu recebo o seguinte erro ao compilar isso:

<source>: In function 'int main()':

<source>:16:9: error: cannot bind non-const lvalue reference of type 'unsigned int&' to an rvalue of type 'unsigned int'

     func(clr);

         ^~~

Eu acho que a variável ( clr) para a qual passo func(unsigned int&)é um lvalue. Posso obter o endereço clre atribuir outro valor a ele. Por que ele se transforma em um rvalue quando tento passar para ele func(unsigned int&)?

Koen
fonte
5
Pergunte a si mesmo: é um enuma unsigned int?
NathanOliver
@ NathanOliver-ReinstateMonica Na minha opinião original, acho que typedef enumnão é um tipo nativo, e o C ++ o trataria como um unsigned inttipo de fato.
31419 Koen
11
A mensagem de erro do GCC é abaixo do ideal neste caso. O Clang dará uma mensagem menos confusa imprimindo o tipo original de clr.
Cpplearner 31/12/19
@ cpplearner sim, é por isso que eu pensei que enum typeé tratar como unsigned intem C ++.
Koen
enum Xé de seu próprio tipo, diferente deint
MM

Respostas:

22

clrem si é um lvalue do tipo Color. Mas a função não aceita a Color. Ele aceita um (referência a) unsigned int. Portanto, o argumento é convertido (implicitamente). E o resultado da conversão é um pré-valor do tipo unsigned int.

eerorika
fonte
11
Sim, eu tento func(Color&)antes de fazer a pergunta, e compila o passe. Eu apenas pensei que C ++ trataria o enumtipo como o unsigned inttipo na compilação. Obrigado pela sua resposta.
31519 Koen
Uma coisa que aumenta a confusão é que C é quase um subconjunto perfeito de C ++. Pelo menos, qualquer coisa que você possa fazer em C, você pode fazer em C ++ com código quase idêntico, especialmente em gcc / clang. Você também precisará de construções dependentes do compilador, como a substituição do C ++ por 'restringir' em C fornecida pelo gcc. As enumerações são diferentes em C e C ++, por exemplo, se someColor for enum, 'someColor = 1' é C legal, mas não C ++.
Erik Alapää
0

tipo de enumeração init e assignment devem ser enumerados dentro; portanto, o tipo de enumeração não pode ser lvalue;

Super homen
fonte
Se eu mudar func(unsigned int&)para func(Color&), o compilador aceita. Então eu acho que a variável do tipo enum é um lvalue.
31419 Koen
não, porque o tipo de enum não pode ser atribuído int enum define outside
superman
Você quer dizer que ainda é um valor? Mas vinculo uma referência não-const lvalue a ela func(Color&)e ela passa.
31419 Koen
Sim, ainda um rvalue, func esta função chave param única atribuição VERMELHO, VERDE, AZUL, (tecla Color &) Caso contrário, será erro.
Superman
você pode ver estas instruções cpp
superman