Могу ли я использовать ограниченное перечисление для отправки тегов C с шаблонами?

#c #templates #generic-programming

#c #шаблоны #generic-программирование

Вопрос:

Шаблон новичка здесь. Я экспериментирую со следующим кодом:

 #include <type_traits>

enum class Thread
{
    MAIN, HELPER
};

template<typename T>
int f()
{
    static_assert(std::is_same_v<T, Thread::MAIN>);
    return 3;
}

int main()
{
    f<Thread::MAIN>();
}
 

На словах я хочу вызвать утверждение во время компиляции, если функция не вызывается из основного потока. По-видимому, компилятор не принимает перечислитель в качестве аргумента шаблона, кричит invalid explicitly-specified argument for template parameter 'T' .

Я знаю, что мог бы использовать две структуры в качестве тегов: struct ThreadMain и struct ThreadHelper . К сожалению, перечисление cass уже используется везде в моем проекте, и я бы предпочел избегать дубликатов. Как я могу повторно использовать существующий класс enum для этой цели?

Комментарии:

1. Ваш шаблон принимает тип . std::is_same_v сравнивает типы . Thread это тип . Но Thread::MAIN и Thread::HELPER не являются типами , они являются значениями типа Thread .

Ответ №1:

Ваш существующий код близок. Вместо использования typename вы можете просто использовать enum class имя напрямую, как параметр шаблона, не относящийся к типу, например:

 template<Thread T>
int f()
{
    static_assert(T == Thread::MAIN);
    return 3;
}
 

Вы static_assert также должны изменить.

Комментарии:

1. 1, однако было бы лучше использовать N для параметра шаблона, отличного от типа (значения), например, для общего стиля с, например template<int N> . T имя параметра может неточно указывать на то, что это параметр tpe, тогда как это не так. Тем более, что его тип не является типичным enum базовым типом.

2. @bloody «было бы лучше» это просто мнение, а не правило или руководство.

3. @JHBonarius Именно так и есть, ну и что?