C++的std::is_same与std::decay

一、背景

有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是int型还是double型呢?

#include 
template

void typeCheck(T data)
{
    // check data type
    //std::cout<< out put the type
}

二、std::is_same

头文件中提供了C++ STL的std::is_same模板。 C++ STL的std::is_same模板用于检查类型A是否与类型B相同。如果两者相同,则返回布尔值true,否则返回false。

模板类型

template 
struct is_same

template 
inline constexpr 
       bool is_same_v
         = is_same::value

用法

std::is_same::value

实例

#include 
#include 
#include 

int main()
{
    //使bool型变量按照false、true的格式输出。
    //如不使用该标识符,那么结果会按照1、0的格式输出。
    std::cout << std::boolalpha;

    // usually true if 'int' is 32 bit
    std::cout << std::is_same::value << ' '; // ~ true
    std::cout << std::is_same::value << ' '; // ~ false

    // same tests as above, except using C++17's `std::is_same_v` format
    std::cout << std::is_same_v << ' ';  // ~ true
    std::cout << std::is_same_v << '\n'; // ~ false

    // compare the types of a couple variables
    long double num1 = 1.0;
    long double num2 = 2.0;
    std::cout << std::is_same_v << '\n'; // true

    // 'float' is never an integral type
    std::cout << std::is_same::value << '\n'; // false

    // 'int' is implicitly 'signed'
    std::cout << std::is_same::value << ' ';          // true
    std::cout << std::is_same::value << ' '; // false
    std::cout << std::is_same::value << '\n';  // true

    system("pause");
    return 0;

}

打印

C++的std::is_same与std::decay_第1张图片 

四、新的问题

std::is_same可以判断两种类似是否一样,那么用在模板里就是利器了,比如直接在编译的时候判断类型

#include 
template
typeCheck(TYPE data)
{
    if(std::is_same::value)
    {
        std::cout<<"int type";
        //do something int 
    }
    else
    {
        //.........
    }
}

让我们试一试

// is_same example
#include 
#include 
#include 

typedef int integer_type;

struct A { 
    int x;
    int y;
};

struct B { 
int x;
int y; 
};

typedef A C;

int main() {
      std::cout << std::boolalpha;
      std::cout << "is_same:" << std::endl;
      std::cout << "int, const int: " << std::is_same::value << std::endl;//false
      std::cout << "int, int&: " << std::is_same::value << std::endl;//false
      std::cout << "int, const int&: " << std::is_same::value << std::endl;//false
      std::cout << "int, integer_type: " << std::is_same::value << std::endl;//true
      std::cout << "A, B: " << std::is_same::value << std::endl;//false
      std::cout << "A, C: " << std::is_same::value << std::endl;//true
      std::cout << "signed char, std::int8_t: " << std::is_same::value << std::endl;//true
      return 0;
}

打印

C++的std::is_same与std::decay_第2张图片

发现std::is_same的判断是很严格的.std::is_same对int和const int\int &\const int&等都是区别对待的,但在写模板函数时,经常会强制指定常引用进行传参,以免进行数据拷贝,这时候is_same就做出了不相等的判断,但是有时候其实我们还是希望TYPE和const TYPE& 是能认为是一样的,这时就需要std::decay进行退化处理。
 

四、std::decay

C++11提供了一个模板类,来为我们移除类型中的一些特性,比如引用、常量、volatile,但是注意不包括指针特性。std::decay 对一个类型进行退化处理,它的实现如下

template< class T >
struct decay {
private:
    typedef typename std::remove_reference::type U;
public:
    typedef typename std::conditional< 
        std::is_array::value,
        typename std::remove_extent::type*,
        typename std::conditional< 
            std::is_function::value,
            typename std::add_pointer::type,
            typename std::remove_cv::type
        >::type
    >::type type;
};

 实例

#include 
#include 

template 
struct decay_equiv : 
    std::is_same::type, U>::type 
{};

int main()
{
    std::cout << std::boolalpha
              << decay_equiv::value << '\n'
              << decay_equiv::value << '\n'
              << decay_equiv::value << '\n'
              << decay_equiv::value << '\n'
              << decay_equiv::value << '\n'
              << decay_equiv::value << '\n';
    return 0;
}

打印

C++的std::is_same与std::decay_第3张图片

 

参考:

C++11的模板类型判断——std::is_same和std::decay_尘中远的博客-CSDN博客_std::decay

std::is_same - cppreference.com

std::decay - cppreference.com

【C++11】C++类型完全退化(拓展std::decay的功能)_几罗星人的博客-CSDN博客_std::decay

你可能感兴趣的:(C++,c++,开发语言)