I have a non-movable structure and a templated class in which I want to have a function that exists only when the type is movable (using enable_if and type_traits). However, it seems that despite std::is_move_constructible_v returns false, the function still exists and can be executed. However, when I changed the code to use requires clause, everything works as intended. Why is that?
#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));
}