enable_if 和 is_move_constructible 允许不可移动类型,但要求不
enable_if with is_move_constructible allows non-movable types, but requires does not
我有一个不可移动的结构和一个模板化的 class,其中我想要一个仅在类型可移动时才存在的函数(使用 enable_if 和 type_traits) .但是,似乎尽管 std::is_move_constructible_v returns false,函数仍然存在并且可以执行。但是,当我更改代码以使用 requires 子句时,一切都按预期进行。
这是为什么?
#include<bits/stdc++.h>
class NonMovable{
public:
NonMovable(const NonMovable&) = default;
NonMovable(NonMovable&&) = delete;
NonMovable& operator =(const NonMovable&) = default;
NonMovable& operator = (NonMovable&&) = delete;
NonMovable() = default;
};
template<typename T>
struct Foo{
template<typename = std::enable_if<std::is_move_constructible_v<T>,bool>>
void foo(T&& t){ // allowed
// ...
}
};
template<typename T>
struct Foo{
void foo(T&& t) requires std::is_move_constructible_v<T>{ // not allowed
// ...
}
};
int main(){
NonMovable nonMovable;
Foo<NonMovable> x;
std::cout << std::is_move_constructible_v<NonMovable> << "\n"; // 0
x.foo(std::move(nonMovable));
}
正如@Nathan Pierson 在评论中提到的,应该有 enable_if_t
而不是 enable_if
如果您只想为非移动可构造类型禁用 foo
函数,您可以将模板参数设为依赖类型:
template<typename T>
struct Foo{
template<class U = T, class = std::enable_if_t<
std::is_same_v<T,U>&&
std::is_move_constructible_v<U>>>
void foo(T&&){ // not allowed
// ...
}
};
我有一个不可移动的结构和一个模板化的 class,其中我想要一个仅在类型可移动时才存在的函数(使用 enable_if 和 type_traits) .但是,似乎尽管 std::is_move_constructible_v returns false,函数仍然存在并且可以执行。但是,当我更改代码以使用 requires 子句时,一切都按预期进行。 这是为什么?
#include<bits/stdc++.h>
class NonMovable{
public:
NonMovable(const NonMovable&) = default;
NonMovable(NonMovable&&) = delete;
NonMovable& operator =(const NonMovable&) = default;
NonMovable& operator = (NonMovable&&) = delete;
NonMovable() = default;
};
template<typename T>
struct Foo{
template<typename = std::enable_if<std::is_move_constructible_v<T>,bool>>
void foo(T&& t){ // allowed
// ...
}
};
template<typename T>
struct Foo{
void foo(T&& t) requires std::is_move_constructible_v<T>{ // not allowed
// ...
}
};
int main(){
NonMovable nonMovable;
Foo<NonMovable> x;
std::cout << std::is_move_constructible_v<NonMovable> << "\n"; // 0
x.foo(std::move(nonMovable));
}
正如@Nathan Pierson 在评论中提到的,应该有 enable_if_t
而不是 enable_if
如果您只想为非移动可构造类型禁用 foo
函数,您可以将模板参数设为依赖类型:
template<typename T>
struct Foo{
template<class U = T, class = std::enable_if_t<
std::is_same_v<T,U>&&
std::is_move_constructible_v<U>>>
void foo(T&&){ // not allowed
// ...
}
};