p0887r1 :
2.3 Фундаментальный базовый метафункциональный блок
Существует два вездесущих идиома для типовых признаков:
- defineОткрытое значение элемента данных с заданным значением
- определяет открытый тип typedef, который называет данный тип
Удивительно, что есть стандартная утилита, предоставляющая первое (std::integral_constant
), но нет стандартной утилиты, обеспечивающей последнее.type_identity
это утилита.Это фундаментальный строительный блок, от которого просто наследуются другие метафункции.Например, remove_const
можно реализовать следующим образом:
template <typename T>
struct remove_const : type_identity<T> {};
template <typename T>
struct remove_const<T const> : type_identity<T> {};
Его реализация проста:
template<class T>
struct type_identity
{
using type = T;
};
Итак, я стараюсь широко использовать type_identity
в своемкоды, включая личную реализацию Detection Idiom :
namespace detail
{
template<class Default,
class AlwaysVoid,
template<class...>
class Op,
class... Args>
struct detector : type_identity<Default> // here
{
using value_t = std::false_type;
};
template<class Default, template<class...> class Op, class... Args>
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
: type_identity<Op<Args...>> // here
{
using value_t = std::true_type;
};
} // namespace detail
// ......
Работает нормально везде, пока я не использовал тестовые наборы libcxx для моей собственной реализации is_destructible
, нижеслучай сбоя:
struct ProtectedDestructor
{
protected:
~ProtectedDestructor()
{}
};
// ......
template<class T>
void
test_is_not_destructible()
{
static_assert(!is_destructible<T>::value, "");
// ......
}
// ......
test_is_not_destructible<ProtectedDestructor>();
live demo :
prog.cc: 83: 47: ошибка: '~ ProtectedDestructor' является защищенным членом'ProtectedDestructor'
с использованием has_dtor = decltype (std :: declval (). ~ U ());^ prog.cc:26:19: note: при создании экземпляра шаблона типа псевдоним has_dtor, запрашиваемый здесь
: type_identity<Op<Args...>>
^
prog.cc: 45: 1: note: при создании класса шаблона detail ::детектор
......
странно, что один раз заменив type_identity
на тривал using type = ......
, компилятор не имеет ошибок , demo .Для другой проверки has_member
, type_identity
работает нормально, demo .
Итак, единственная проблема здесь, для защищенного dtor, type_identity
заставит struct detail::detector
проверяйте действительность dtor, пока using type = something
не будет.
Я думаю, что решение простое, просто удалите type_identity
и используйте using type = something
напрямую, как оригинальная реализация Уолтера Е. Брауна .Но вопрос в следующем:
почему type_idintity
ломается здесь, а trival using type = something
нет?