c++ - enable_if 和 is_move_constructible 允许不可移动类型,但 require 不允许

标签 c++ templates type-traits enable-if

我有一个不可移动的结构和一个模板类,我希望其中有一个仅当类型可移动时才存在的函数(使用enable_if和type_traits)。然而,尽管 std::is_move_constructible_v 返回 false,该函数似乎仍然存在并且可以执行。但是,当我将代码更改为使用需要子句时,一切都按预期进行。 这是为什么?

#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));
}

最佳答案

如果您只想对不可移动的可构造类型禁用该 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
        // ...
    }
};

Demo

关于c++ - enable_if 和 is_move_constructible 允许不可移动类型,但 require 不允许,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67878203/

相关文章:

C++ 两个 is_union_or_class 实现

c++ - 为什么要在结构中保留内存?

c++ - 将函数应用于元组中的每个元素,将每个元素转换为类型包中的不同类型,然后作为参数包传递

android - OpenGL 性能

c++ - 显式特化导致实例化?

c++ - 模板 : get proper variable name from type name

c++ - 使用 std::remove_pointer 等操作在模板中构建派生类型

c++ - 如何在模板变量定义中引入static_assert

c++ - 显示二维数组中两边的总和

c++ - 在多 map 中搜索值