Под «универсальным» я подразумеваю успешную работу с const &
и кастомными удалениями. Может быть, есть способ проверить все умные указатели сразу?
Я хочу написать некоторую функцию для проверки пустого варианта, если он содержит только указатели (необработанные, уникальные, общие) и проверить его создание с помощью std::enable_if
, но что я должен написать в условии?
template <typename... T>
std::enable_if_t<???, bool>
IsEmptyVariantOfPointers(const std::variant<T...>& variant) {
bool emptyVariant = true;
std::visit([&emptyVariant](auto&& arg) {
emptyVariant = arg == nullptr;
}, variant);
return emptyVariant;
}
ПРИМЕЧАНИЕ. Меня интересует вариант без перегрузки функции шаблона по типам указателей.
умные указатели на самом деле не являются указателями. Не существует универсального способа определить сообразительность. Предположим, вы используете библиотеку с именем foo
, тогда вы только из документации знаете, является ли foo::bar
каким-то умным указателем или нет.
Может есть способы проверить сразу все умные указатели?
Вы можете написать трейт, который проверяет, что тип переданного класса шаблона является определенным типом класса шаблона, следующим образом:
template<typename Type, template<typename...> class Args>
struct is_specialization_of final : std::false_type {};
template<template<typename...> class PointerType, typename... Args>
struct is_specialization_of<PointerType<Args...>, PointerType> final: std::true_type {};
Теперь предоставьте шаблон переменной типа bool, который проверяет классы шаблона (т. е. интеллектуальные указатели или любые классы пинтера клиента).
template<typename PointerType>
inline constexpr bool is_std_smart_ptr =
is_specialization_of<PointerType, std::unique_ptr>::value
|| is_specialization_of<PointerType, std::shared_ptr>::value;
Это можно использовать в std::enable_if_t
следующим образом. Для простоты я заменил переменные аргументы шаблона простым аргументом шаблона. Я оставляю вариативную версию вам.
template <typename T>
std::enable_if_t<is_std_smart_ptr<T>, bool>
IsEmptyVariantOfPointers(const std::variant<T>& variant) {
// .....
}
Какие есть универсальные способы проверки is_unique_ptr?
Если фактическое намерение состоит только в том, чтобы найти std::unique_ptr
(один из способов), вы можете написать для него специальные черты.
template <typename...> struct is_std_unique_ptr final : std::false_type {};
template<class T, typename... Args>
struct is_std_unique_ptr<std::unique_ptr<T, Args...>> final : std::true_type {};
Что случилось с final
на чертах? Наследование одного признака от другого является допустимым вариантом использования. Например, это делает std::conjunction.
Финал @HolyBlackCat здесь необязателен. (ИМХО) Нечего придираться к глупости. Кстати, выражение fold пригодится вместо std::conjunction
или подобных признаков, если ::value
является шаблонной переменной.
непонятно, что вы хотите проверить. Если
T
этоstd::unique_ptr<X>
?