C++11 autoとdecltype導出規則


VS 2015テスト:decltype:
class Foo {};

int &func_int_r(void) { int i = 0; return i; };
int &&func_int_rr(void) { return 0; };
int func_int(void) { return 0; };

const int &func_cint_r(void) { int i = 0; return i; };
const int &&func_cint_rr(void) { return 0; };
const int func_cint(void) { return 0; };
const Foo func_cfoo(void) { return Foo(); };


int main()
{
    {
        int x = 0;
        decltype(func_int_r()) al = x;  // al -> int &
        decltype(func_int_rr()) bl = 0; // bl -> int &&
        decltype(func_int()) cl = 0;    // cl -> int


        decltype(func_cint_r()) a2 = x; // a2 -> const int &
        decltype(func_cint_rr()) b2 = 0;    // b2 -> const int &&
        decltype(func_cint()) c2 = 0;   // c2 -> int
        decltype(func_cfoo()) d2 = Foo();   // d2 -> Foo


        decltype((x)) t = x;    // t -> int &
        decltype(x + 1) t2; // t2 -> int  
        decltype(++x) t3 = x;   // t3 -> int &   decltype((++x)) t4 = x; // t6 -> int &

        decltype((1)) t5 = x;   // t4 -> int
        decltype(1) t6 = x; // t5 -> int

        int i = 0;
    }

    system("pause");
    return 0;
}
  • 関数が右の値を返すと、decltypeはcvオペレータを捨てます.c2,d2
  • 識別子に()を付けると、decltypeの結果は左の値で参照されます.t,t4
  • 式が左に割り当てられた場合、decltypeの結果は左に参照されます.t 3-その他は簡単に導き出せばよい.適用:
  • template<class ContainerT>
    class Foo
    {
        typename ContainerT::iterator it_; // 
    public:
        void func(ContainerT& container)
        {
            it_ = container.begin();
        }
    };
    
    
    
    int main()
    {
        typedef const vector<int> container_t;
        container_t arr;
    
        Foo<container_t> foo;
        foo.func(arr);
    
        system("pause");
        return 0;
    }

    Containertがconstの場合it_const_のはずですiterator;解決方法:
    template<class ContainerT>
    class Foo
    {
    private:
        //decltype(ContainerT().begin()) it_;// vs2015 ,ContainerT() vector<int> ,const , 。
        decltype(std::declval<ContainerT>().begin()) it_;// 
        static ContainerT gi;// 
        decltype(gi.begin())   it_; // , , auto 
    public:
        void func(ContainerT& container)
        {
            decltype(ContainerT()) tt;
            it_ =container.begin();
            int i = 0;
        }
    };
    
    
    
    int main()
    {
        using container_t= const vector<int> ;
        container_t arr;
    
        Foo<container_t> foo;
        foo.func(arr);
    
        system("pause");
        return 0;
    }

    タイプのバックグラウンド構文を返します.
    template<typename U,typename R>
    auto add(U u, R r)->decltype(u + r)
    {
        return u + r;
    }
    
    
    int main()
    {
        cout << add(100, 100.0f) << endl;
        cout<<add<int,float>(100, 100.0f) << endl;
        system("pause");
        return 0;
    }

    auto:
  • autoの後に&が明示的に追加されると、式cv制限子および参照が保持されます.
  • auto導出結果がポインタである場合、cvオペレータは保持される.
  • その他の場合、cv限定子および参照は保持されない.
  • int main()
    {
    
        int x = 0;
        const auto* a = &x; // a -> const int *
        auto b = &x;    // b -> int *
        auto &c = x;    // c -> int &
        auto d = c; // d -> int
        const auto e = x;   // e -> const int
        auto f = e; // f -> int
    
        const auto& g = x;  // g -> const int &
        auto& h = g;    // h -> const int &
        const auto i = g;   // i -> const int
        auto j = a; // j -> const int *
    
        const int ci = i, &cr = ci;
        auto d1 = &i;   // d1 -> const int *
        auto e1 = &ci;  // e1 -> const int *
    
        system("pause");
        return 0;
    }