48

考虑以下程序:

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符?

4

5 回答 5

47

我更喜欢auto i = decltype(e){0};这个。它比 using 简单一些type_traits,而且我觉得它更明确地指定了您希望将变量初始化为 0e类型的意图。

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

于 2013-10-07T22:51:03.440 回答
45

使用std::remove_const

#include<type_traits>
...
for (std::remove_const<decltype(e)>::type i{0}; i < e; ++i)
于 2013-10-07T22:00:32.713 回答
13

您还可以使用std::decay

#include<type_traits>
...
for (std::decay<decltype(e)>::type i{}; i < e; ++i) {
  // do something
}
于 2018-02-01T10:39:42.227 回答
8

尚未提及的解决方案:

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

原始类型的 prvalues 已const被剥离;so+e是类型的纯右值int,因此decltype(+e)int

于 2018-02-01T10:48:08.707 回答
0

我更喜欢范围。模拟它非常容易。

#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;
}
于 2013-10-08T05:05:43.897 回答