2.3 Фундаментальный метафункциональный строительный блок
Есть два вездесущих идиома для типовых черт:
- определить общедоступное значение элемента данных с заданным значением
- определить открытый тип 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
широко в моих кодах, в том числе личной реализации Идиома обнаружения:
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>();
prog.cc:83:47: ошибка: ‘~ ProtectedDestructor’ является защищенным членом ‘ProtectedDestructor’
использование has_dtor = decltype (std :: declval (). ~ U ());
^
prog.cc:26:19: примечание: при создании экземпляра типа шаблона здесь запрашивается псевдоним has_dtor: type_identity<Op<Args...>> ^
prog.cc:45:1: note: в экземпляре класса шаблона ‘detail :: detector
……
Это странно, что однажды заменить type_identity
с тривалом using type = ......
, компилятор не имеет ошибки, демонстрация. Для другого тривала has_member
проверять, type_identity
работает отлично, демонстрация.
Итак, единственная проблема здесь, для защищенного Dtor, type_identity
заставит структуру detail::detector
проверить действительность дтора, пока using type = something
не буду.
Я думаю, что решение простое, просто удалите type_identity
и использовать using type = something
прямо как Оригинальная реализация Уолтера Э. Брауна. Но вопрос в том,
Почему type_idintity
перерыв здесь, пока тривал using type = something
не?
Задача ещё не решена.
Других решений пока нет …