迭代所有 char 值的更简单、可移植的方法?
Simpler, portable way to iterate over all char values?
对于我正在教的 class,我需要编写一段代码来遍历所有可能的 char
值。我想以一种可移植到不同的 C++ 实现中的方式来做到这一点。这意味着
- 我不能假设
char
是 signed
或 unsigned
,
- 我不能假设
char
是八位,
- 我不能假设
sizeof(int) > 1
,
- 我不能假设
int32_t
等类型存在,
- 我不能假设整数溢出不会陷阱,
- 等等
我想到的最佳解决方案是以下不寻常的 do ... while
循环:
char ch = numeric_limits<char>::min();
process(ch);
do {
ch++;
process(ch);
} while (ch != numeric_limits<char>::max());
这种方法可行,但我觉得它很笨拙。直觉上可能需要这样的方法是有道理的,因为增量的数量比可能的字符数量多一个,但也许有一种根本不同的方法可用,它更类似于传统的 for
循环。
有没有比这更简单的便携式方法来实现这一点?
but perhaps there's a fundamentally different approach available that more closely resembles a traditional for loop.
好吧,你 可以 使用实际的 for
循环:
#include <limits>
#include <iostream>
void process(char ch)
{
std::cout << static_cast<long>(ch) << ' ';
}
int main()
{
for ( char ch = std::numeric_limits<char>::min(); ; ++ch )
{
process(ch);
if ( ch == std::numeric_limits<char>::max() )
break;
}
std::cout << '\n';
}
您可以创建一个看起来像容器的包装器 class。
struct Chars {
enum {
Chars_MIN = std::numeric_limits<char>::min(),
Chars_MAX = std::numeric_limits<char>::max()
};
struct Iterator {
char c_;
bool end_;
Iterator (char c, bool e = false) : c_(c), end_(e) {}
auto & operator ++ () {
if (c_ == Chars_MAX) end_ = true;
else ++c_;
return *this;
}
auto operator * () const { return c_; }
auto operator == (const Iterator &other) const {
return c_ == other.c_ && end_ == other.end_;
}
auto operator != (const Iterator &other) const {
return !(*this == other);
}
};
Iterator begin () const { return Iterator(Chars_MIN); }
Iterator end () const { return Iterator(Chars_MAX, true); }
};
然后,您可以使用现代 for
语法:
Chars ccc;
for (auto x : ccc) {
process(x);
}
对于我正在教的 class,我需要编写一段代码来遍历所有可能的 char
值。我想以一种可移植到不同的 C++ 实现中的方式来做到这一点。这意味着
- 我不能假设
char
是signed
或unsigned
, - 我不能假设
char
是八位, - 我不能假设
sizeof(int) > 1
, - 我不能假设
int32_t
等类型存在, - 我不能假设整数溢出不会陷阱,
- 等等
我想到的最佳解决方案是以下不寻常的 do ... while
循环:
char ch = numeric_limits<char>::min();
process(ch);
do {
ch++;
process(ch);
} while (ch != numeric_limits<char>::max());
这种方法可行,但我觉得它很笨拙。直觉上可能需要这样的方法是有道理的,因为增量的数量比可能的字符数量多一个,但也许有一种根本不同的方法可用,它更类似于传统的 for
循环。
有没有比这更简单的便携式方法来实现这一点?
but perhaps there's a fundamentally different approach available that more closely resembles a traditional for loop.
好吧,你 可以 使用实际的 for
循环:
#include <limits>
#include <iostream>
void process(char ch)
{
std::cout << static_cast<long>(ch) << ' ';
}
int main()
{
for ( char ch = std::numeric_limits<char>::min(); ; ++ch )
{
process(ch);
if ( ch == std::numeric_limits<char>::max() )
break;
}
std::cout << '\n';
}
您可以创建一个看起来像容器的包装器 class。
struct Chars {
enum {
Chars_MIN = std::numeric_limits<char>::min(),
Chars_MAX = std::numeric_limits<char>::max()
};
struct Iterator {
char c_;
bool end_;
Iterator (char c, bool e = false) : c_(c), end_(e) {}
auto & operator ++ () {
if (c_ == Chars_MAX) end_ = true;
else ++c_;
return *this;
}
auto operator * () const { return c_; }
auto operator == (const Iterator &other) const {
return c_ == other.c_ && end_ == other.end_;
}
auto operator != (const Iterator &other) const {
return !(*this == other);
}
};
Iterator begin () const { return Iterator(Chars_MIN); }
Iterator end () const { return Iterator(Chars_MAX, true); }
};
然后,您可以使用现代 for
语法:
Chars ccc;
for (auto x : ccc) {
process(x);
}