gpt4 book ai didi

c++ - 什么是实现 is_swappable 以测试 Swappable 概念的正确方法?

转载 作者:IT老高 更新时间:2023-10-28 22:30:01 28 4
gpt4 key购买 nike

我认为 is_swappable 的“正确”实现如下:

template<class T, class U = T> struct is_swappable<T, U> : /* see below */ { }

is_swappable 继承自 std::true_type如果 T 和 U 是 Swappable , 否则来自 std::false_type .


我尝试了很多方法,但 SFINAE 似乎不起作用。这是一个特别讨厌的反例:

struct A {
A() {}
~A() {}
A(const A&) = delete;
A(A&&) = delete;
};

显然 A 不是 Swappable .然而,我能提出的任何通用解决方案都无法正确处理上述示例。

我尝试过但没有成功的 SFINAE 实现如下所示:

namespace with_std_swap {
using std::swap;

template<class T, class U, class =
decltype(swap(std::declval<T&>(), std::declval<U&>()))>
std::true_type swappable_test(int);

template<class, class> std::false_type swappable_test(...);
}

template<class T, class U = T>
struct is_swappable
: decltype(with_std_swap::using_std_swap::swappable_test<T, U>(0)) { };

有没有办法在没有编译器帮助的情况下编写 is_swappable 代码?

最佳答案

基于@jrok 的回答,我们可以通过编写一个 swap 函数来判断一个不合格的 swap 调用是否会调用 std::swapstd::swap 相同的签名,但可以检查的唯一返回类型:

namespace detail2 {
struct tag {};

template<class T>
tag swap(T&, T&);

template<typename T>
struct would_call_std_swap_impl {

template<typename U>
static auto check(int)
-> std::integral_constant<bool, std::is_same<decltype( swap(std::declval<U&>(), std::declval<U&>())), tag>::value>;

template<typename>
static std::false_type check(...);

using type = decltype(check<T>(0));
};

template<typename T>
struct would_call_std_swap : would_call_std_swap_impl<T>::type { };
}

那么is_swappable的定义就变成了:

template<typename T>
struct is_swappable :
std::integral_constant<bool,
detail::can_call_swap<T>::value &&
(!detail2::would_call_std_swap<T>::value ||
(std::is_move_assignable<T>::value &&
std::is_move_constructible<T>::value))
> { };

我们还需要一个特殊情况来交换数组:

template<typename T, std::size_t N>
struct is_swappable<T[N]> : is_swappable<T> {};

关于c++ - 什么是实现 is_swappable 以测试 Swappable 概念的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26744589/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com