Тип C ++ 11 для различия между классом enum и обычным enum

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

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) Поплавок удваивается

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

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

15

Решение

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

#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 стандарта C ++ 11:

Значение перечислителя или объекта типа перечисления с незаданной областью преобразуется в целое число посредством интегрального преобразования (4.5). […] Обратите внимание, что это неявное преобразование перечисления в 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!");
}

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

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

Благодаря Дэниел Фрей для указания на то, что мой предыдущий подход будет работать только до тех пор, пока не определена пользовательская перегрузка operator +,

23

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]