C++类型萃取

当我们遇到这样的场景时,我们会用到类型萃取

template<class T>
void Copy(T* dst, T* str, size_t n)//模板函数copy
{
    memcpy(dst, str, n*sizeof(str));
}
void test()
{
    string s1[10] = { "aaaaaaaaaaaaa", "wwww", "iiii" };
    string s2[10] = { "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "zzzzzaaaaaaaaaaaaaaaaa", "mmmmmmmmmmmmmmmmmvvbbb" };
    int l1[10] = { 1, 2, 3, 4 };
    int l2[10] = { 4, 5, 6, 78, 9 };
    Copy(s1, s2, 10);
    Copy(l1, l2, 10);
    for (size_t i = 0; i < 10; i++)
    {
        cout << s1[i] << " ";
    }
    cout << endl;
    for (size_t i = 0; i < 10; i++)
    {
        cout << l1[i] << " ";
    }
    cout << endl;

}

这是一个copy函数,当它copy string[]时会出错,原因是memcopy是按字节拷贝,再拷贝string是会出错(浅拷贝);遇到这种问题时,有两种解决方案:1.for循环拷贝、2.类型萃取;但当考虑到效率时我们会用到memcpy,故我们需要将两种情况结合使用时,这时选择类型萃取就比较合适了(将memcpy和for循环拷贝视情况而用);

通过这个例子,了解到我们为什么要用类型萃取

代码:

struct _FalseType//类型
{ };
struct _TrueType//类型
{ };
template <class T>
struct _TypeTraits
{
    typedef _FalseType IsPODType;//内嵌类型重定义
};
template<>
struct _TypeTraits<int>//内嵌类型
{
    typedef _TrueType IsPODType;
};
template<class T>
void Copy(T* dst, const T* str, size_t n)
{
    _copy(dst, str, n, _TypeTraits<T>::IsPODType());//_copy能够推演出两份代码,拷贝string和一般类型(如int)
}
template<class T>
void _copy(T* dst, const T* str, size_t n, _FalseType)
{
    for (size_t i = 0; i < n; i++)
    {
        dst[i] = str[i];
    }
}
template<class T>
void _copy(T* dst, const T* str, size_t n, _TrueType)
{
    memcpy(dst, str, n*sizeof(str));
}
void test()
{
    string s1[10] = { "aaaaaaaa", "zzzzzz", "ccccc" };
    string s2[10] = { "cccccccccccc", "wwwwwwww", "ddddd" };
    Copy(s1, s2, 10);
    for (size_t i = 0; i < 10; i++)
    {
        cout << s1[i] << " ";
    }
    cout << endl;
}

这里写图片描述

通_TypeTraits::IsPODType()获取信息是一般类型还是string类型从而推演出两份代码;如下图是类型萃取实现的整体过程从_copy(dst, str, n, _TypeTraits::IsPODType());出发将所有类型推演:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/fangxiaxin/article/details/78576239