现代C++技术研究(4)---引用折叠规则

C++11对类型推导遵守所谓引用折叠规则(reference collapsing)。举个例子:

#include 
#include 

int main()
{
    using T = const int;
    using TR = T&;
    // case 1
    using ResultType = TR;
    bool isCnstInt = std::is_same::value;
    bool isCnstIntRef = std::is_same::value;
    bool isCnstIntRightRef = std::is_same::value;
    if (isCnstInt) {
        std::cout << "Case1:ResultType is const int\n";
    } else if (isCnstIntRef) {
        std::cout << "Case1:ResultType is const int&\n";
    } else if (isCnstIntRightRef) {
        std::cout << "Case1:ResultType is const int&&\n";
    }
    // case 2
    using ResultType2 = TR&;
    bool isCnstInt2 = std::is_same::value;
    bool isCnstIntRef2 = std::is_same::value;
    bool isCnstIntRightRef2 = std::is_same::value;
    if (isCnstInt2) {
        std::cout << "Case2:ResultType is const int\n";
    } else if (isCnstIntRef2) {
        std::cout << "Case2:ResultType is const int&\n";
    } else if (isCnstIntRightRef2) {
        std::cout << "Case2:ResultType is const int&&\n";
    }
    // case 3
    using ResultType3 = TR&&;
    bool isCnstInt3 = std::is_same::value;
    bool isCnstIntRef3 = std::is_same::value;
    bool isCnstIntRightRef3 = std::is_same::value;
    if (isCnstInt3) {
        std::cout << "Case3:ResultType is const int\n";
    } else if (isCnstIntRef3) {
        std::cout << "Case3:ResultType is const int&\n";
    } else if (isCnstIntRightRef3) {
        std::cout << "Case3:ResultType is const int&&\n";
    }
    using TR2 = T&&;
    // case 4
    using ResultType4 = TR2;
    bool isCnstInt4 = std::is_same::value;
    bool isCnstIntRef4 = std::is_same::value;
    bool isCnstIntRightRef4 = std::is_same::value;
    if (isCnstInt4) {
        std::cout << "Case4:ResultType is const int\n";
    } else if (isCnstIntRef4) {
        std::cout << "Case4:ResultType is const int&\n";
    } else if (isCnstIntRightRef4) {
        std::cout << "Case4:ResultType is const int&&\n";
    }
    // case 5
    using ResultType5 = TR2&;
    bool isCnstInt5 = std::is_same::value;
    bool isCnstIntRef5 = std::is_same::value;
    bool isCnstIntRightRef5 = std::is_same::value;
    if (isCnstInt5) {
        std::cout << "Case5:ResultType is const int\n";
    } else if (isCnstIntRef5) {
        std::cout << "Case5:ResultType is const int&\n";
    } else if (isCnstIntRightRef5) {
        std::cout << "Case5:ResultType is const int&&\n";
    }
    // case 6
    using ResultType6 = TR2&&;
    bool isCnstInt6 = std::is_same::value;
    bool isCnstIntRef6 = std::is_same::value;
    bool isCnstIntRightRef6 = std::is_same::value;
    if (isCnstInt6) {
        std::cout << "Case6:ResultType is const int\n";
    } else if (isCnstIntRef6) {
        std::cout << "Case6:ResultType is const int&\n";
    } else if (isCnstIntRightRef6) {
        std::cout << "Case6:ResultType is const int&&\n";
    }
    return 0;
}

这个小程序的测试结果是:

[root@192 moderncpp]# ./reference_collapse
Case1:ResultType is const int&
Case2:ResultType is const int&
Case3:ResultType is const int&
Case4:ResultType is const int&&
Case5:ResultType is const int&
Case6:ResultType is const int&&

我们可以把测试结果整理成如下表格:

C++11中的引用折叠规则
TR的类型定义 ResultType的类型定义 ResultType的类型推导结果
T& TR T&
T& TR& T&

T&

TR&& T&
T&& TR T&&
T&& TR& T&
T&& TR&& T&&

可以看出,对于TR的类型定义或者ResultType的类型定义,只要出现左值引用,那么类型推导结果一定是左值引用,在没有左值引用的情况下,如果出现右值引用,那么类型推导结果会是右值引用。

参考资料:

《深入理解C++11:C++11新特性解析与应用》

你可能感兴趣的:(C/C++技术,c++)