web-dev-qa-db-ja.com

decltypeを使用して、constなしで式のタイプを取得する

次のプログラムを検討してください。

int main ()
{
    const int e = 10;

    for (decltype(e) i{0}; i < e; ++i) {
        // do something
    }
}

これはclang(およびgcc)でコンパイルできません:

decltype.cpp:5:35: error: read-only variable is not assignable
    for (decltype(e) i{0}; i < e; ++i) {
                                  ^ ~

基本的に、コンパイラはiがconstであるため、eはconstである必要があると想定しています。

decltypeのタイプを取得するためにeを使用できますが、const指定子を削除する方法はありますか?

37
Jim Garrison

これにはauto i = decltype(e){0};を使用します。 type_traitsを使用するよりも少し簡単です。また、変数をeの型の0に初期化する意図をより明示的に指定しているように感じます。

私は最近 Herbの "AAAスタイル" を頻繁に使用しているので、私の部分に偏りがあるかもしれません。

34
Casey

使用する - std::remove_const

#include<type_traits>
...
for (std::remove_const<decltype(e)>::type i{0}; i < e; ++i)
40
zch

std::decay

#include<type_traits>
...
for (std::decay<decltype(e)>::type i{}; i < e; ++i) {
  // do something
}
6
klaus

まだ言及されていない解決策:

_for (decltype(+e) i{0}; i < e; ++i)
_

プリミティブ型の値はconstが取り除かれています。したがって、_+e_はint型のprvalueであるため、decltype(+e)intです。

5
M.M

私はrange-forを好みます。シミュレーションは非常に簡単です。

#include <iostream>

template< typename T >
struct range_t
{
    struct iter
    {
        T operator * ()const noexcept { return n;}
        iter& operator ++()noexcept{ ++n; return *this;}
        friend
        bool operator != (iter const& lhs, iter const& rhs)noexcept
        { return lhs.n != rhs.n;}

        T n;
    };

    iter begin()const noexcept {return {b};}
    iter end() const noexcept{ return {e};}
    T b, e;
};
template< typename T > range_t<T>  range(T b, T e){ return {b,e}; }

int main()
{
    const int e = 10;

    for( auto i : range(0,e) )
    {
        std::cout << i << ' ';
    }
    return 0;
}
1