提问人:paolo 提问时间:3/26/2023 更新时间:3/26/2023 访问量:63
std::is_swappable_v 在可交换类模板上为 false
std::is_swappable_v is false on a swappable class template
问:
我正在尝试编写一个可交换的类模板。如果可交换,我想要并且是可交换的(例如 应该是可交换的
替换为 )。所以我选择了这样的东西:S<T>
S<T>
S<T&>
T
S<int>
S<int&>
#include <type_traits>
namespace n {
template <typename T>
struct S {};
// Overload #1
template <typename T, typename U>
void swap(S<T>&, S<U>&) {}
// Overload #2
// template <typename T>
// void swap(S<T>&, S<T>&) {}
} // namespace n
int main() {
n::S<int> sInt;
swap(sInt, sInt);
// static_assert(std::is_swappable_v<decltype(sInt)>);
// ^ assertion fails unless I uncomment #2
n::S<int&> sIntRef;
swap(sInt, sIntRef);
static_assert(
std::is_swappable_with_v<decltype(sInt)&, decltype(sIntRef)&>);
// ^ assertion evaluates the way I expect
}
正如你在上面看到的,即使
调用编译。为了计算到 ,我需要取消 的重载。is_swappable_v<n::S<int>>
false
swap(sInt, sInt)
is_swappable_v<n::S<int>>
true
#2
swap
我是做错了什么,还是实际上是类型特征
应该以这种方式工作吗?std::is_swappable
答:
3赞
Artyer
3/26/2023
#1
表达式实际上不执行交换,因为 std::swap
不可见(通过 )。swap(sInt, sInt)
using std::swap;
当你拥有它时:
int main() {
n::S<int> sInt;
using std::swap;
swap(sInt, sInt);
}
它不会编译,因此您的类型实际上无法与自身交换。
这样做的原因是有两个可能的重载:
template <typename T, typename U>
void n::swap(S<T>&, S<U>&);
// with T = int, S = int
template <typename T>
void std::swap(T&, T&);
// with T = n::S<int>
第一个会更好,因为每个论点都更专业。
第二个会更好,因为两个参数是相同的,并且它们来自同一个模板参数。
由于它们都以不同的方式更好,因此它成为一个模棱两可的电话。
添加第二个模板重载时:
template <typename T>
void n::swap(S<T>&, S<T>&);
// with T = int
这比第一个更好,因为反复论证,也比因为它更专业,所以它被明确地选择。n::swap
std::swap
评论
static_assert