现代C++技术研究(2)---模板类型推导(2)

第二种情况:ParamType是一个通用引用(Universal Reference)

这种情况,模板类型推导的结果,就不那么直观了。看如下测试用例:

#include <iostream>
#include <type_traits>

template<typename T> void f(T&& param)
{
    using ParamType = T&&;
    bool TIsInt = std::is_same<T, int>::value;
    bool TIsConstInt = std::is_same<T, const int>::value;
    bool TIsIntRef = std::is_same<T, int&>::value;
    bool TIsConstIntRef = std::is_same<T, const int&>::value;
    if (TIsInt) {
        std::cout << "T is int, ";
    } else if (TIsConstInt) {
        std::cout << "T is const int, ";
    } else if (TIsIntRef) {
        std::cout << "T is int&, ";
    } else if (TIsConstIntRef) {
        std::cout << "T is const int&, ";
    } 
    bool ParamTypeIsIntRef = std::is_same<ParamType, int&>::value;
    bool ParamTypeIsConstIntRef = std::is_same<ParamType, const int&>::value;
    bool ParamTypeIsIntRefRef = std::is_same<ParamType, int&&>::value;
    if (ParamTypeIsIntRef) {
        std::cout << "param's type is int&\n";
    } else if (ParamTypeIsConstIntRef) {
        std::cout << "param's type is const int&\n";
    } else if (ParamTypeIsIntRefRef) {
        std::cout << "param's type is int&&\n";
    }
}

int main()
{
    int x = 27; // x is an int
    const int cx = x; // cx is a const int
    const int& rx = x; // rx is a reference to x as a const int
    f(x);  // x is lvalue, so T is int&, param's type is int&
    f(cx); // cx is lvalue, so T is const int&, param's type is const int&
    f(rx); // rx is lvalue, so T is const int&, param's type is const int&
    f(27); // 27 is rvalue, so T is int, param's type is int&&
    return 0;
}

可以看到,对于左值,T和ParamType类型相同,对于右值,T去引用,而ParamType是右值引用。

第三种情况:ParamType既不是指针也不是引用

1)传入的参数是引用情况:

#include <iostream>
#include <type_traits>

template<typename T> void f(T param)
{
    using ParamType = T;
    bool TIsInt = std::is_same<T, int>::value;
    bool TIsConstInt = std::is_same<T, const int>::value;
    if (TIsInt) {
        std::cout << "T is int, ";
    } else if (TIsConstInt) {
        std::cout << "T is const int, ";
    }
    bool ParamTypeIsInt = std::is_same<ParamType, int>::value;
    bool ParamTypeIsConstInt = std::is_same<ParamType, const int>::value;
    if (ParamTypeIsInt) {
        std::cout << "param's type is int\n";
    } else if (ParamTypeIsConstInt) {
        std::cout << "param's type is const int\n";
    }
}

int main()
{
    int x = 27; // x is an int
    const int cx = x; // cx is a const int
    const int& rx = x; // rx is a reference to x as a const int
    f(x); // T is int, param's type is int
    f(cx); // T is int, param's type is int
    f(rx); // T is int, param's type is int
    return 0;
}

可以看到,推导出的类型,T和ParamType是相同的,并且const和引用都被去掉了。

2)传入的参数是指针的情况:

#include <iostream>
#include <type_traits>

using PtrType = const char* const;

template<typename T> void f(T param)
{
    using ParamType = T;
    bool TIsCstCharPoint = std::is_same<T, const char*>::value;
    bool TIsCstCharPointCst = std::is_same<T, const int* const>::value;
    if (TIsCstCharPoint) {
        std::cout << "T is const char*, ";
    } else if (TIsCstCharPointCst) {
        std::cout << "T is const char* const, ";
    }
    bool ParamTypeIsCstCharPoint = std::is_same<ParamType, const char*>::value;
    bool ParamTypeIsCstCharPointCst = std::is_same<ParamType, const int* const>::value;
    if (ParamTypeIsCstCharPoint) {
        std::cout << "param's type is const char*\n";
    } else if (ParamTypeIsCstCharPointCst) {
        std::cout << "param's type is const char* const\n";
    }
}

int main()
{
    const char* const ptr = "Fun with pointers"; // ptr is const pointer to const object
    f(ptr); // T is const char*, param's type is const char*
    return 0;
}

可以看到,推导出的类型,T和ParamType是相同的,并且后面的const被去掉了,注意,前面的const属性是不能去掉的。

小结:

1)当ParamType是一个通用引用时,传入左值参数,模板的类型推导ParamType结果是左值引用,且ParamType和T相同,传入右值参数,模板的类型推导ParamType结果是右值引用,但ParamType和T是不同的,T去掉引用。

2)当模板参数是值传递时,const和volatile等修饰都会被去掉,且ParamType和T相同。

参考资料:

《Effective Mordern C++》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值