使用decltype获取表达式的类型,不使用const

时间:2013-10-07 21:55:56

标签: c++ c++11 decltype

考虑以下计划:

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是。

我是否可以使用decltype获取e的类型,但删除const说明符?

5 个答案:

答案 0 :(得分:36)

使用std::remove_const

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

答案 1 :(得分:33)

我更喜欢auto i = decltype(e){0};。它比使用type_traits简单一点,我觉得它更明确地指定了你想要一个变量初始化为e类型的0的意图。

我最近一直在使用Herb's "AAA Style",所以这可能只是我的偏见。

答案 2 :(得分:6)

您还可以使用std::decay

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

答案 3 :(得分:2)

尚未提及的解决方案:

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

原始类型的Prvalues已剥离const;因此+eint类型的prvalue,因此decltype(+e)int

答案 4 :(得分:1)

我更喜欢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;
}