std::decay结合cppreference理解

文章详细解析了C++中的`std::decay`模板以及类型转换规则,特别关注了函数指针和数组的特殊处理,通过示例展示了`is_decay_equ`和类型转换的等价性。

#include <type_traits>
#include "stdio.h"
template<typename T, typename U>
constexpr bool is_decay_equ = std::is_same_v<std::decay_t<T>, U>;
int func(float num) {return num;}
struct S
{
    void f_ref() & {}
    void f_const() const {}
};
int main()
{
    static_assert
    (
        is_decay_equ<int, int> &&
        ! is_decay_equ<int, float> &&
        is_decay_equ<int&, int> &&
        is_decay_equ<int&&, int> &&
        is_decay_equ<const int&, int> &&
        is_decay_equ<int[2], int*> &&
        ! is_decay_equ<int[4][2], int*> &&
        ! is_decay_equ<int[4][2], int**> &&
        is_decay_equ<int[4][2], int(*)[2]> &&
        is_decay_equ<int(int), int(*)(int)>
    );
    printf("1 %s\n",is_decay_equ<int[4][2], int(*)[2]>?"true":"false");
    printf("2 %s\n",is_decay_equ<int(int), int(*)(int)>?"true":"false");
/**
 * https://en.cppreference.com/w/cpp/types/decay 
 * template< class T >
struct decay;
 * Performs the type conversions equivalent to the ones performed when passing function arguments by value. Formally:

1) If T is "array of U" or reference to it, the member typedef type is U*.
2) Otherwise, if T is a function type F or reference to one?, the member typedef type is std::add_pointer<F>::type.
3) Otherwise, the member typedef type is std::remove_cv<std::remove_reference<T>::type>::type.
*/
    printf("3 %s\n",is_decay_equ<int(float),std::add_pointer_t<int(float)>>?"true":"false");  // true
    typedef int(*funcRef)(float);
    printf("4 %s\n",std::is_same_v<funcRef,std::add_pointer_t<int(float)>>?"true":"false");   // true,对应3)
    printf("5 %s\n",std::is_same_v<funcRef,int(*)(float)>?"true":"false");   // true,对应3)
    printf("6 %s\n",std::is_same_v<funcRef,int(float)>?"true":"false");   // false
    //int(*funcRef)(float)&;
    //funcRef = = func;
}

### C++ 中 `std::decay` 的作用和用法 #### 定义与模板声明 `std::decay` 是 C++ 标准库中的一个工具,位于头文件 `<type_traits>` 中。该工具用于去除类型的修饰符并转换为裸类型。具体来说,对于给定的类型 `T`,`std::decay<T>::type` 将返回经过处理后的类型[^3]。 ```cpp #include <type_traits> template <class T> struct decay; template <class T> using decay_t = typename decay<T>::type; ``` #### 处理不同类型的效果 - **左值引用**:当应用于非常量左值引用时,`std::decay` 会将其转换为目标类型的副本形式;即由 `Type&` 转变为 `Type`。 - **右值引用**:如果应用到临时对象或者显式的移动语义,则同样会被简化成对应的非限定版本,也就是从 `Type&&` 变更为 `Type`。 - **数组类型**:遇到固定大小或多维数组的情况下,最终得到的是指向单个元素的指针,例如 `int[10]` 经过衰变之后成为 `int*`。 - **函数类型**:针对函数签名而言,结果是指向相同原型函数的指针,比如 `void(int)` 结果是 `void(*)(int)`。 然而需要注意两点特殊情形: - 对于类类型,`std::decay` 并不改变其本质属性,因此在这些情况下不会产生任何影响[^1]。 - 同样地,在面对指针本身的时候也不会有变化发生,这意味着无论是常量还是变量指针都将保持原状不变[^2]。 #### 实际应用场景举例 下面通过几个简单的例子来展示如何利用这个特性实现更灵活的设计模式或是优化编译期计算逻辑: ```cpp // 示例一:自动推导参数实际传递方式 template<typename T> auto process(T&& param){ using DecayedParam = std::decay_t<T>; // 进一步操作... } // 示例二:辅助宏定义帮助构建泛型代码片段 #define MAKE_SHARED(type, ...) \ std::make_shared<std::remove_reference_t<type>>(__VA_ARGS__) // 示例三:确保容器内部存储一致性的适配器设计 template<class Container> typename std::enable_if< !std::is_same_v< typename Container::value_type, std::decay_t<decltype(*Container().begin())> > >::type adapt_container(Container&) { // 执行必要的调整措施... } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值