Передать перечисление с классом enum по ссылке

Я следующий код вот что я думаю должны компиляции, но не работает.

#include <cstdint>

typedef uint8_t testtype;

enum testenum : uint8_t {
};

void foo(uint8_t& v) {}

int main() {
    testtype bar;
    foo(bar);

    testenum baz;
    foo(baz);

    return 0;
}

Я получаю следующую ошибку:

prog.cpp:15:9: error: invalid initialization of non-const reference of type 'uint8_t& {aka unsigned char&}' from an rvalue of type 'uint8_t {aka unsigned char}'
  foo(baz);

на мой взгляд, это должно работать, потому что все имеет один и тот же базовый тип (uint8_t). Переменная typedef'Ed может быть передана в foo функция, но перечисление (которое имеет класс перечисления uint8_t) не может.

в моем проекте это означает, что я не могу передать все свои перечисления одному перегруженная функция - похоже, я должен создать перегрузку для каждого возможного перечисления.

есть ли элегантный способ получить это для компиляции, или мне нужно передать перечисление через вторую переменную, которую я могу передать по ссылке?

1 ответов


перечисления в C++ - это больше, чем просто применение имени к целому числу; у нас есть const int переменные для этого. Перечисления концептуально представляют целое число, которое должно хранить только одно из набора определенных значений.

Typedefs-это псевдонимы; они во всех отношениях идентичны данному типу. Перечисленияdistinct типы. Они используют свои базовые типы, и они могут быть преобразовать, а не то же самое введите в качестве базового типы.

таким образом, ссылка на uint8_t - это не то же самое, что ссылка на перечисление, даже если это перечисление используется uint8_t в качестве базового типа. Таким образом, преобразование из ссылки на перечисление в ссылку на базовый тип является незаконным преобразованием, а также нарушением строгого псевдонима.

вы можете передать его по значению, так как неклассовые перечисления неявно конвертируются в их базовые типы. И вы можете пройти мимо const&, так как неявное преобразование может создать временно, чтобы заполнить эту ссылку. Но вы не можете передать перечисление функции, которая принимает не -const ссылка на целое число.