Мой текущий вопрос был вдохновлен, пытаясь понять, как std::unique_ptr<T, D>
использует механику шаблонов для создания экземпляра шаблона класса размер T*
при D
(тип Deleter) тип лямбда-функция, но большего размера, когда D
является указателем на функцию type (так как пространство должно быть выделено в экземпляре unique_ptr
для хранения указателя функции).Как std :: is_empty <T> реализован в VS2015 (или любом компиляторе)?
Глядя через исходный код VS2015, я считаю, что std::unique_ptr
происходит от std::_Unique_ptr_base
, который, в свою очередь, заявляет член данных типа _Compressed_pair<class _Ty1, class _Ty2, bool = is_empty<_Ty1>::value && !is_final<_Ty1>::value>
. В этом последнем контексте тип _Ty1
является типом дебетера, D
, то есть вторым параметром шаблона unique_ptr
, отмеченным в предыдущем абзаце; то есть мотивация, стоящая за этим вопросом, заключается в том, что я сопоставляю _Ty1
как лямбда-тип, а _Ty1
- тип указателя функции. (На самом деле, значение по умолчанию bool
в настоящее время используются.)
Я понимаю, что is_empty<_Ty1>::value
является true
, когда _Ty1
является экземпляром типа лямбды (при лямбда не имеет переменный захват и, следовательно, имеет 0 размера); но это false
, когда _Ty1
- тип указателя функции.
Это привело меня к тому, чтобы определить, как определяется std::is_empty
.
Ugh!
Ниже приведена полная реализация std::is_empty
, которую я могу найти в исходном коде библиотеки VS2015 C++.
В файле type_traits
это:
// TEMPLATE CLASS is_empty
template<class _Ty>
struct is_empty _IS_EMPTY(_Ty)
{ // determine whether _Ty is an empty class
};
... и макро _IS_EMPTY
определяется в том же файле:
#define _IS_EMPTY(_Ty) \
: _Cat_base<__is_empty(_Ty)>
... и в этот момент моя удача иссякает , потому что я не могу найти определение __is_empty
в любом месте. У меня есть GREPped через весь каталог установки VS2015 (который включает, я думаю, весь исходный код библиотеки C++, хотя, возможно, я ошибаюсь).
Мне нравится понимать внутренние элементы C++, когда захочу. Но ... Я застрял на этом, и много поисковых запросов не выявило ответа (хотя я видел ссылку на intrinsics), и мое копание не ... обнаружило какой-либо исходный код.
Может кто-нибудь просветить эту ситуацию? Как работает std::is_empty<T>
в VS2015 или, если на то пошло, какой-либо другой компилятор?
Я не уверен в этом, но в соответствии со стандартом пустой класс имеет размер 1 байт. можно измерить размер класса и определить. Я действительно не пытался это реализовать –
@DavidHaim - Это рассуждение связано с ответом, который предоставляет Dietmar Kühl. В примере в его ответе он использует тот факт, что, когда непустой класс проистекает из пустого класса, пустой объект subobject * does * имеет размер 0 - это только тогда, когда класс полностью пуст, включая все базовые class subobjects, что класс должен иметь ненулевой размер. –