- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
比方说,我有一个容器 c
类型,它提供了一个 size()
方法,我想遍历这个容器,同时跟踪每个项目的索引:
for (/*TODO*/ i = 0; i < c.size(); i++) {...}
在后 C++11 时代,自动类型推导可以很好地解决许多问题。我们应该用什么来代替上面的 TODO
?无论 size()
的类型是什么,对我来说唯一正确的是:
for (decltype(c.size()) i = 0; i < c.size(); i++) {...}
但这似乎过于冗长,而且在我看来,不利于可读性。
另一种解决方案可能是这样的:
for (auto end = c.size(), i = 0; i < end; i++) {...}
但这也无助于提高可读性,当然,与原始片段的语义也不相同。
所以,我的问题是:在仅给定索引限制的类型的情况下,推断循环索引变量类型的最佳方法是什么。
最佳答案
对文本中第一个问题的简短回答:您应该将 /*TODO*/
替换为 unsigned
, std::size_t
或类似的东西,意思是:不必推导类型,只需选择适合任何合理容器大小的类型即可。
这将是一个无符号的、相当大的类型,因此编译器不会因为可能的精度损失而对您大喊大叫。在上面的评论中,您写道 size_t
不是 保证 是 decltype(c.size())
的良好替代品,但是虽然它实现一个索引与 size_t
不兼容的容器并非不可能,这样的索引肯定不是数字(因此与 i = 0
不兼容),并且容器也不会有 size
方法。 size()
方法意味着一个非负积分,并且由于 size_t
是为精确的这些数字而设计的,因此几乎不可能有一个大小不能为以它为代表。
你的第二个问题是关于如何推断类型的,你已经提供了最简单但不完美的答案。如果你想要一个不像 decltype
那样冗长并且不像 auto end
那样令人惊讶的解决方案,你可以为起始索引定义一个模板别名和一个生成器函数在一些实用程序标题中:
template <class T>
using index_t = decltype(std::declval<T>().size());
template <class T, class U>
constexpr index_t<T> index(T&&, U u) { return u; }
//and then in the actual location of the loop:
for (auto i = index(c,0); i < c.size(); ++i) {...}
//which is the same as
for (auto i = index_t<std::vector<int>>(0); i < c.size(); ++i) {...}
如果你想要一个更通用的索引类型,例如对于没有 size
方法的数组和类,它会变得有点复杂,因为模板别名可能不是专门的:
template <class T>
struct index_type {
using type = decltype(std::declval<T>().size());
};
template <class T>
using index_t = typename index_type<T>::type;
template <class T, class U>
constexpr index_t<T> index(T&&, U u) { return u; }
//index_type specializations
template <class U, std::size_t N>
struct index_type<U[N]> {
using type = decltype(N);
};
template <>
struct index_type<System::AnsiString::AnsiString> { //YUCK! VCL!
using type = int;
};
但是,这只是针对您实际需要索引且简单的 foreach 循环不够用的少数情况的大量内容。
关于c++ - For循环索引类型推导最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26135284/
我是一名优秀的程序员,十分优秀!