C++ Проверка условий в шаблонах и зачем нужно *= при использовании type traits
Всем привет! Я видел некоторый код с type traits, где вместо
template <typename T, typename enable_if_t<..something>>
Делают примерно так:
template <typename T, typename enable_if_t<..something>*=nullptr>
Или так:
template <typename T, typename = enable_if_t<..something>>
Чем отличаются все эти 3 записи?(надеюсь я в них не ошибся) И второй вопрос: как лучше всего делать проверки на различные условия(для типов) в шаблонах?
Ответы (1 шт):
Есть два популярных способа:
typename = std::enable_if_t<??>std::enable_if_t<??, std::nullptr_t> = nullptr
Второй способ лучше, по двум причинам:
Нельзя отключить проверку, передав какой-то свой тип в этот шаблонный аргумент.
Можно сделать несколько функций, которые будут отличаться только условием. Если сделать это с первым способом, то компилятор будет ругаться на переопределение функции.
У второго способа есть разные вариации: std::enable_if_t<??, int> = 0, std::enable_if_t<??> * = nullptr (что эквивалентно std::enable_if_t<??, void *> = nullptr), и т. п. Но они плохи тем, что позволяют сгенерировать несколько разных копий шаблона, передав туда разные шаблонные аргументы. А у std::nullptr_t возможное значение только одно, поэтому с ним так не сделать. (В С++20 для этих целей также подходит какой-нибудь пустой класс.)