Подтвердить что ты не робот

С++ 11, чтобы различать класс enum и регулярное перечисление

Я пишу псевдоним шаблона продвижения, похожий на boost:: promotion, но для С++ 11. Цель этого - избегать предупреждений при извлечении аргументов из функций varidic. например.

template <typename T>
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList)
{
    std::vector<T> args;
    while (aArgCount > 0)
    {
        args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>)));
        --aArgCount;
    }
    return args;
}

Псевдоним шаблона Promote поддерживает тип, следующий за продвижением аргументов по умолчанию для вариативных аргументов: 1) Целое число, меньшее, чем int, увеличивается до int 2) Поплавок продвигается до двойного

Моя проблема в том, что стандартное перечисление С++ может быть продвинуто, но класс enum С++ 11 не продвигается (компилятор не генерирует предупреждение). Я хочу, чтобы Promote работал с регулярным перечислением, но игнорировал класс перечисления С++ 11.

Как я могу рассказать о различии между классом enum и перечислением в моем псевдониме шаблона Promote?

4b9b3361

Ответ 1

Вот возможное решение:

#include <type_traits>

template<typename E>
using is_scoped_enum = std::integral_constant<
    bool,
    std::is_enum<E>::value && !std::is_convertible<E, int>::value>;

В решении используется различие в поведении между подсчетом и не областью перечисления, указанными в параграфе 7.2/9 стандарта С++ 11:

Значение перечислителя или объекта неперечисленного типа перечисления преобразуется в целое число путем цельной рекламы (4.5). [...] Обратите внимание, что это неявное преобразование enum to int не предоставляется для перечисления с областью. [...]

Вот демонстрация того, как вы его используете:

enum class E1 { };
enum E2 { };
struct X { };

int main()
{
    // Will not fire
    static_assert(is_scoped_enum<E1>::value, "Ouch!");

    // Will fire
    static_assert(is_scoped_enum<E2>::value, "Ouch!");

    // Will fire
    static_assert(is_scoped_enum<X>::value, "Ouch!");
}

А вот живой пример.

БЛАГОДАРНОСТЬ:

Спасибо Daniel Frey за то, что мой предыдущий подход будет работать только до тех пор, пока не будет определена пользовательская перегрузка operator +.