почему type_identity нарушает реализацию is_detected

p0887r1:

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 не?

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]