考虑以下计划:
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
说明符?
答案 0 :(得分:36)
#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
;因此+e
是int
类型的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;
}