基于以空结尾的字符串上的循环的范围
Range based for loops on null terminated strings
我假设基于范围的 for 循环将支持 C 样式字符串
void print_C_str(const char* str)
{
for(char c : str)
{
cout << c;
}
}
然而,事实并非如此,标准[stmt.ranged] (6.5.4)
说基于范围的for在3种可能性之一中工作:
- 范围是一个数组
- 范围是具有可调用
begin
和end
方法的类 - 在关联的命名空间(加上
std
命名空间)中可以访问 ADL
当我在全局命名空间中添加begin
和end
const char*
函数时,我仍然收到错误(来自VS12和GCC 4.7)。
有没有办法让基于范围的 for 循环来处理 C 样式字符串?
我尝试向namespace std
添加重载,这有效,但据我了解,向namespace std
添加重载是非法的(这是正确的吗?
如果为以 null 结尾的字符串编写一个简单的迭代器,则可以通过在返回特殊范围的指针上调用函数来实现此目的,而不是将指针本身视为范围。
template <typename Char>
struct null_terminated_range_iterator {
public:
// make an end iterator
null_terminated_range_iterator() : ptr(nullptr) {}
// make a non-end iterator (well, unless you pass nullptr ;)
null_terminated_range_iterator(Char* ptr) : ptr(ptr) {}
// blah blah trivial iterator stuff that delegates to the ptr
bool operator==(null_terminated_range_iterator const& that) const {
// iterators are equal if they point to the same location
return ptr == that.ptr
// or if they are both end iterators
|| is_end() && that.is_end();
}
private:
bool is_end() {
// end iterators can be created by the default ctor
return !ptr
// or by advancing until a null character
|| !*ptr;
}
Char* ptr;
}
template <typename Char>
using null_terminated_range = boost::iterator_range<null_terminated_range_iterator<Char>>;
// ... or any other class that aggregates two iterators
// to provide them as begin() and end()
// turn a pointer into a null-terminated range
template <typename Char>
null_terminated_range<Char> null_terminated_string(Char* str) {
return null_terminated_range<Char>(str, {});
}
用法如下所示:
for(char c : null_terminated_string(str))
{
cout << c;
}
我不认为这会失去任何表现力。实际上,我认为这一点更清楚。
一种可能的解决方法是将以 null 结尾的字符串包装在另一种类型中。最简单的实现如下(它的性能不如 R. Martinho Fernandes 的建议,因为它调用strlen
但它的代码也明显较少)。
class null_terminated_range {
const char* p:
public:
null_terminated_range(const char* p) : p(p) {}
const char * begin() const { return p; }
const char * end() const { return p + strlen(p); }
};
用法:
for(char c : null_terminated_range(str) )
C 字符串不是一个数组,它不是一个具有 begin
/end
成员的类,并且您不会通过 ADL 找到任何内容,因为参数是原语。可以说,这应该是普通的非限定查找,使用 ADL,它将在全局命名空间中找到一个函数。但是,鉴于措辞,我认为这是不可能的。
相关文章:
- 在循环C++中指定字符串之后,不会打印该字符串
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- C++-字符串是否包含一个带有简单循环的单词
- 在 c++ 中查找字符串中没有循环的数字总和
- 比较两个字符串后卡在无限循环中
- C++ - 使用基于范围的 for 循环将字符值分配给向量中的字符串不会分配值
- 而循环跳过 cin.getline() 对于 C 字符串
- 我正在尝试使用 while 循环从字符串中删除字母,直到没有字母。我在这里做错了什么?
- 如何使用将字符串拆分为 for 循环中的变量的程序
- 是否有可能实现O(N)时间和O(1)空间解决方案,以实现C++中的字符串循环移位
- 循环访问还包含未使用元素的字符串数组
- 循环访问资源字符串表
- C++ - 使用用户输入的字符串数据检查结构字符串数据(无限执行 while 循环)
- 修改向量中的字符串?(不使用循环)
- 试图突破字符串循环
- C++和Java的字符串循环性能比较
- 无法通过字符串循环我的程序以将其从英语翻译成猪拉丁语
- C++ 字符串循环检查相同的单词
- 为什么 javascript 中不使用字符串循环的C++语法?