Как вы обнаружили, проблема заключалась в том, что вы должны использовать std::true_type{}
с конечными фигурными скобками в конце decltype()
Так что
decltype( <other elements>, std::true_type )
невернои выдает ошибку, где
decltype( <other elements>, std::true_type{} )
// .......................................^^
работает.
Дело в том, что decltype()
возвращает тип, заданный для сущности (переменная, константа и т. д.) или выражениеэтого типа;так (по примеру), учитывая decltype(3)
, вы получите int
.
Если вы напишите
decltype( std::true_type )
, вы спросите тип типа, и это неправильно.
Если вы пишете
decltype( std::true_type{} )
, вы запрашиваете тип элемента (std::true_type{}
) типа std::true_type
;это правильно, и вы получите std::true_type
.
Я предлагаю другой способ:
decltype( std::declval<std::true_type>() )
, где std::declval()
- стандартная функция шаблона (только объявленная, но достаточная для decltype()
которые возвращают элемент полученного типа шаблона.
Итак, std::declval<std::true_type>()
является выражением типа std::true_type
и decltype()
return, очевидно, std::true_type
.
В случаеТип, который является конструируемым по умолчанию, вы можете создать сущность этого типа, просто добавив пару фигурных скобок в конце имени типа. Но когда тип не является конструируемым по умолчанию, вы не можете решить, почему.
С помощью std::declval()
вы также получаете выражение заданного типа, когда этот тип не является конструктивным по умолчанию.
В случае std::true_type
вы можете решить обоими способами, но я предлагаю использовать всегда std::declval()
все равно.