【学习enable_if模板, 学习unqiue_str 删除操作】

发布于:2024-11-03 ⋅ 阅读:(120) ⋅ 点赞:(0)

enable_if 是 C++ 标准库中的一个模板结构体,它用于条件编译和 SFINAE(Substitution Failure Is Not An Error)。enable_if 的主要作用是通过条件编译来控制模板的实例化,从而实现条件编译和 SFINAE。

1. enable_if 的基本用法如下:

在这里插入图片描述

#include <iostream>
#include <type_traits>

template<typename T>
struct MyStruct {
    // 当 T 是指针类型时,MyStruct 被实例化
    MyStruct(T* p) : ptr(p) {}

    void print() const {
        if (ptr != nullptr) {
            std::cout << "Pointer value: " << *ptr << std::endl;
        } else {
            std::cout << "Pointer is null" << std::endl;
        }
    }

    T* ptr;
};

int main() {
    // 使用指针类型
    int* p = nullptr;
    MyStruct<int*> ms1(p);

    // 使用非指针类型
    int i = 0;
    // MyStruct<int> ms2(i); // 错误:不能将 int 转换为 MyStruct<int>

    // 调用 print 函数
    ms1.print();

    return 0;
}

在这里插入图片描述

2. enable_if 的另一个常见用法是在函数模板中使用它,以实现 SFINAE。例如:

template<typename T>
typename std::enable_if<std::is_arithmetic<T>::value, void>::type
print() {
    std::cout << "Arithmetic type" << std::endl;
}

template<typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, void>::type
print() {
    std::cout << "Non-arithmetic type" << std::endl;
}

在这个例子中,std::enable_if 被用来控制 print 函数模板的实例化。当 T 是算术类型(如 int、float 等)时,std::is_arithmetic::value 为 true,std::enable_if 将生成一个类型 void,因此 print 被实例化,并输出 “Arithmetic type”。当 T 不是算术类型时,std::is_arithmetic::value 为 false,std::enable_if 将生成一个类型 void,因此 print 不被实例化,print 的另一个实例化版本将被选择。

总之,enable_if 是一个非常有用的工具,它可以用于条件编译和 SFINAE,从而使得模板编程更加灵活和安全。
在这里插入图片描述

实现利用偏特化模板

template<bool B, class T = void>
struct enable_if {};
 
template<class T>
struct enable_if<true, T> { typedef T type; };

可以进一步阅读。
https://blog.csdn.net/wangx_x/article/details/122867422

3. unique_ptr 中删除指针,使用了SFINAE

template <typename _Up>
typename enable_if<is_convertible<_Up (*)[], _Tp (*)[]>::value>::type //注意这里的类型是数组的指针
                                //虽然允许派生类指针隐式的转换为基类指针,为了检查这种转换,我们要写成这样
                                //例如可以从non-const 转换为const,但不能从derived ** 转换为 base **
operator()(_Up *__ptr) const {
  static_assert(sizeof(_Tp) > 0, "can't delete pointer to incomplete type");
  //调用delete[]
  delete[] __ptr;
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到