Различные синтаксисы шаблонов для определения аргумента - класса или нет.

При чтении этого вопроса я наткнулся на @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 >

надеюсь, что это полезно для вас:)