如何检查类型"T"是否为C++中的"std::p air<?,bool>"?



我们可以定义一个函数,将多个值插入到一个集合中,如下所示:

template <typename T, typename... U>
bool insert_all(T& to, const U... arguments) {
return (to.insert(arguments).second && ...);
}

所以这个代码可以插入4,5和6到集合:

std::set set { 1, 2, 3 };
insert_all(set, 4, 5, 6);

显然,类型T可能是一个没有接受int的方法的类型,称为insert并返回std::pair<?, bool>。有必要通过SFINAE:进行检查

template <typename T, typename U, typename = void>
struct can_insert : std::false_type {
};
template <typename T, typename U>
struct can_insert<T, U, 
std::enable_if_t<std::is_same_v<decltype(std::declval<T>().insert(std::declval<U>())), std::pair<typename T::iterator, bool>>, void>
> : std::true_type {
};
template <typename T, typename U>
inline constexpr auto can_insert_v = can_insert<T, U>::value;

注意第二个...std::pair<typename T::iterator, bool>>...,如何像java代码? extends Pair<?, Boolean>一样优雅地表达它?

这与您已经编码的技术没有太大区别:

#include <tuple>
#include <type_traits>
template<typename T>
struct is_pair_t_and_bool : std::false_type {};
template<typename T>
struct is_pair_t_and_bool<std::pair<T, bool>> : std::true_type {};
static_assert( is_pair_t_and_bool<std::pair<char, bool>>::value );
static_assert( !is_pair_t_and_bool<int>::value );
static_assert( !is_pair_t_and_bool<std::pair<int, int>>::value );

而且,在C++20中,一旦你走了那么远,你还不如把它作为一个概念:

template<typename T>
concept pair_t_and_bool=is_pair_t_and_bool<T>::value;
template<pair_t_and_bool T>
struct something {};
something<std::pair<int, bool>> this_compiles;
something<std::pair<int, int >> this_doesnt_compile;

在C++20概念的帮助下,您可以将can_insert定义为concept,如:

template<class T, class U>
concept can_insert = std::ranges::range<T> &&
requires(T& to, const U argument) {
{ to.insert(argument) } -> 
std::same_as<std::pair<std::ranges::iterator_t<T>, bool>>;
};

然后用它来约束像一样的insert_all

template<typename T, typename... U>
requires (can_insert<T, U> && ...)
bool insert_all(T& to, const U... arguments) {
return (to.insert(arguments).second && ...);
}

最新更新