• auto类型推导和打印


    #include "gtest/gtest.h"
    
    #include <iostream>
    #include <type_traits>
    #include <typeinfo>
    
    #ifndef _MSC_VER
    #include <cxxabi.h>
    #endif
    
    #include <memory>
    #include <string>
    #include <cstdlib>
    
    using namespace std;
    
    template <class T>
    std::string type_name()
    {
        typedef typename std::remove_reference<T>::type TR;
        std::unique_ptr<char, void(*)( void* )> own
        (
        #ifndef _MSC_VER
                abi::__cxa_demangle(typeid( TR ).name(), nullptr,
                    nullptr, nullptr),
        #else
                nullptr,
        #endif
            std::free
        );
        std::string r = own != nullptr ? own.get() : typeid( TR ).name();
        if (std::is_const<TR>::value)
            r += " const";
        if (std::is_volatile<TR>::value)
            r += " volatile";
        if (std::is_lvalue_reference<T>::value)
            r += "&";
        else if (std::is_rvalue_reference<T>::value)
            r += "&&";
        return r;
    }
    
    #define TYPENAME(obj) string(#obj).append(": <").append(string(type_name<decltype(obj)>())).append(">")
    #define DUMPTYPE(obj) cout << TYPENAME(obj) << endl;
    
    
    
    class Foo {
    private:
        int a{1};
        int *ptr = &a;
    public:
        int& getRef() {return a;}
        const int& getConstRef() {return a;}
        int* getPtr() {return ptr;}
        const int* getConstPtr() {return ptr;}
    
        //-----------------------------------------------
        auto getR() -> int& {return a;}     // 和getRef一样,需要用auto&接收;
        // auto& getR1() -> int {return a;} // 不能这样写 —— error: ‘getR1’ function with trailing return type has ‘auto&’ as its type rather than plain ‘auto’
            // 【trailing return type,如果是引用,只能写在后面】
        auto getR2() -> decltype((a)) {return a;} // 注意
        auto getR3() -> decltype(std::ref(a)) {return a;} // 可以编过,但是会变成<std::reference_wrapper<int>>
    
        // auto getCR() -> int& const {return a;} // 不能这样写 —— error: ‘const’ qualifiers cannot be applied to ‘int&’
        const auto getCR() -> int& {return a;}
        const auto getCR1() -> decltype((a)) {return a;}
    
        // auto getP() -> int* {return ptr;}; // 也不能这样写 —— error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
        // auto getP() -> decltype(int*) {return ptr;}; // 这样写也不行 —— error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
        auto getP() -> decltype(ptr) {return ptr;}; // 只能这样写
        const auto getCP() -> decltype(ptr) {return ptr;}
        //-----------------------------------------------
    };
    
    void testFunc() {
        Foo foo;
        auto valueGetRef = foo.getRef();            DUMPTYPE(valueGetRef); // 丢失引用
        auto valueGetConstRef = foo.getConstRef();  DUMPTYPE(valueGetConstRef); // 丢失引用和const
        const auto cValueGetRef = foo.getRef();     DUMPTYPE(cValueGetRef);
    
        auto& refGetConstRef = foo.getConstRef();           DUMPTYPE(refGetConstRef);   // 丢失const
        const auto& cRefGetConstRef = foo.getConstRef();    DUMPTYPE(cRefGetConstRef);
        const auto& cRefGetRef = foo.getRef();              DUMPTYPE(cRefGetRef);   // 即使获取的不是const,用const auto&接收也会变成const
        auto&& universalRefGetConstRef = foo.getConstRef(); DUMPTYPE(universalRefGetConstRef);
    
        //-----------------------------------------------
        auto valueGetR = foo.getR();        DUMPTYPE(valueGetR);
        // auto valueGetR1 = foo.getR1();   DUMPTYPE(valueGetR1);
        auto valueGetR2 = foo.getR2();      DUMPTYPE(valueGetR2);
        auto valueGetR3 = foo.getR3();      DUMPTYPE(valueGetR3); // 不能这样使用:valueGetR3 = 2; 因为获得的不是引用
    
        auto& refGetR = foo.getR();         DUMPTYPE(refGetR);
        // auto& refGetR1 = foo.getR1();    DUMPTYPE(refGetR1);
        auto& refGetR2 = foo.getR2();       DUMPTYPE(refGetR2);
        const auto& cRefGetR2 = foo.getR2();    DUMPTYPE(cRefGetR2);
    
        auto valueGetCR = foo.getCR();      DUMPTYPE(valueGetCR);
        auto valueGetCR1 = foo.getCR1();    DUMPTYPE(valueGetCR1);  
        auto& refGetCR = foo.getCR();       DUMPTYPE(refGetCR);  
        auto& refGetCR1 = foo.getCR1();     DUMPTYPE(refGetCR1);
        const auto& cRefGetCR = foo.getCR1();     DUMPTYPE(cRefGetCR);
        const auto& cRefGetCR1 = foo.getCR1();    DUMPTYPE(cRefGetCR1);
    
        auto valueGetP = foo.getP();        DUMPTYPE(valueGetP);
        auto valueGetCP = foo.getCP();      DUMPTYPE(valueGetCP);
        // auto& refGetP = foo.getP();         DUMPTYPE(refGetP); // error: cannot bind non-const lvalue reference of type ‘int*&’ to an rvalue of type ‘int*’
    
        //-----------------------------------------------
    }
    
    void t1();
    
    TEST(TestAuto, TestAuto)
    {
        auto x = 27;            DUMPTYPE(x);
        auto &rx = x;           DUMPTYPE(rx);
        const auto cx = x;      DUMPTYPE(cx);
        const auto &crx = x;    DUMPTYPE(crx);
        auto px = &x;           DUMPTYPE(px);
        const auto cpx = &x;    DUMPTYPE(cpx);
    
        auto &&uref1 = x;   DUMPTYPE(uref1);
        auto &&uref2 = rx;  DUMPTYPE(uref2);
        auto &&uref3 = cx;  DUMPTYPE(uref3);
        auto &&uref4 = cx;  DUMPTYPE(uref4);
        auto &&uref5 = 27;  DUMPTYPE(uref5);
    
        const char name[] = "a b b";    DUMPTYPE(name);
        auto arr1 = name;               DUMPTYPE(arr1);
        auto &arr2 = name;              DUMPTYPE(arr2);
    
        auto x1 = 27;           DUMPTYPE(x1);
        auto x2(27);            DUMPTYPE(x2);
        auto x3 = {27};         DUMPTYPE(x3);
        auto x3_2 = {27,28};    DUMPTYPE(x3_2);
        auto x4{27};            DUMPTYPE(x4);
    //    auto x5{27,38}; //error
    /*
    main.cpp:67:15: error: direct-list-initialization of ‘auto’ requires exactly one element [-fpermissive]
      auto x5{27,38}; //error
                   ^
    main.cpp:67:15: note: for deduction to ‘std::initializer_list’, use copy-list-initialization (i.e. add ‘=’ before the ‘{’)
    */
    
        testFunc();
        t1();
    }
    
  • 相关阅读:
    TIM时钟频率计算
    时钟节拍tick
    Continue作用
    struct结构体的字节长度,字节对齐
    IAR所包含的头文件位置
    Oracle存储过程给变量赋值的方法
    DataTable如何去除重复的行
    C#遍历窗体所有控件或某类型所有控件
    SqlServer无备份下误删数据恢复
    45.4.7 序列:USER_SEQUENCES(SEQ)
  • 原文地址:https://www.cnblogs.com/owxc/p/15647536.html
Copyright © 2020-2023  润新知