Как проверить, является ли тип умным указателем или ссылкой на умный указатель - PullRequest
1 голос
/ 02 февраля 2020

Я пытаюсь реализовать структуру, которая проверяет во время компиляции, является ли данный тип интеллектуальным указателем или ссылкой на интеллектуальный указатель.

Я переписал это решение (которое делает не работает для ссылок):

template<typename T, typename Enable = void>
struct IsSmartPointer : std::false_type {
};

template<typename T>
struct IsSmartPointer<T,
        typename std::enable_if<
                std::is_same<
                        typename std::decay_t<T>, std::unique_ptr<typename std::decay_t<T>::element_type>
                >::value
        >
> : std::true_type {
};

template<typename T>
struct IsSmartPointer<T,
        typename std::enable_if<
                std::is_same<
                        typename std::decay_t<T>, std::shared_ptr<typename std::decay_t<T>::element_type>
                >::value
        >
> : std::true_type {
};

template<typename T>
struct IsSmartPointer<T,
        typename std::enable_if<
                std::is_same<
                        typename std::decay_t<T>, std::weak_ptr<typename std::decay_t<T>::element_type>
                >::value
        >
> : std::true_type {
};

Я чувствую, что эта реализация очень близка к правильному решению. Однако приведенный ниже код печатает нули:

std::cout << IsSmartPointer<int>::value                          << '\n'
          << IsSmartPointer<const std::shared_ptr<int> &>::value << '\n'
          << IsSmartPointer<std::shared_ptr<int> &>::value       << '\n'
          << IsSmartPointer<const std::shared_ptr<int>>::value   << '\n'
          << IsSmartPointer<std::shared_ptr<int>>::value
          << std::endl;

Не могли бы вы попытаться найти ошибку, потому что у меня закончились идеи?

1 Ответ

2 голосов
/ 02 февраля 2020

Вы написали std::enable_if<...>, когда оно должно быть std::enable_if_t<...> или std::enable_if<...>::type.

std::enable_if<...> - это отдельный тип, который никогда не будет void. Таким образом, ваши частичные специализации никогда не будут использоваться, если для второго аргумента шаблона по умолчанию установлено значение void.


Также обратите внимание, что вы забыли пользовательские средства удаления. std::unique_ptr имеет второй аргумент шаблона для пользовательского типа удалителя, который вы не поймете, если он не указан по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...