Различные синтаксисы шаблонов для определения аргумента - класса или нет.
При чтении этого вопроса я наткнулся на @Johannes.
template<typename> struct void_ { typedef void type; };
template<typename T, typename = void> // Line 1
struct is_class { static bool const value = false; };
template<typename T>
struct is_class<T, typename void_<int T::*>::type> { // Line 2
static bool const value = true;
};
Эта конструкция находит, если данный тип является классом или нет. Меня озадачивает новый вид синтаксиса для написания этой небольшой метапрограммы. Может кто-нибудь объяснить подробно:
- Почему нам нужна строка 1?
- В чем смысл синтаксиса
<int
T::*>
как параметр template
в строке
2?
Ответы
Ответ 1
Строка 1: выбор частичной специализации ниже, если тест завершен.
Строка 2: int T::*
действительна только в том случае, если T
- тип класса, так как он обозначает указатель на член.
Таким образом, если оно действительно, void_<T>::type
дает void
, имея эту частичную специализацию, выбранную для экземпляра с a value
of true
.
Если T
не относится к типу класса, то эта частичная специализация отсутствует из-за SFINAE и по умолчанию возвращается к общему шаблону с value
из false
.
Каждый раз, когда вы видите T::SOMETHING
, если SOMETHING
нет, будь то тип, член данных или простое определение указателя, вы получаете SFINAE.
Ответ 2
1. строка 1 используется для чего-то, что не является классом, например int, long и т.д.
например:
class foo {};
if (is_class<foo>::value) // is a class
line_2 called
else // if not
line 1 called
из-за частичной специализации, поэтому строка 1 - это то, что вам нужно, иначе вы получите сообщение об ошибке, если вы передадите тип, который не является классом (например, char *, long, int... )
2: ключ int T:: * is ":: *", это стандартный оператор в С++
означает, что указатель указывает на член класса, может быть как функцией, так и полем данных,
и в этом случае это означает любого, кто имеет член или может работать с указателем-членом, это работает только для классов, структур или союзов в С++, поэтому в результате вы узнаете параметр является или нет классом.
btw, google некоторые ключевые слова, такие как: С++ template, характеристика частичной специализации и , или strong >
надеюсь, что это полезно для вас:)