4 c++
使用for_each迭代NULL终止的字符串是可能的:
const char *name = "Bob";
void func(const char &arg)
{
cout << arg;
}
int main()
{
for_each(name, name + strlen(name), func);
}
Run Code Online (Sandbox Code Playgroud)
对于NULL终止的字符串列表,可能类似的事情(不必首先确定列表的总长度),例如:
const char *names[] = { "Bob", "Adam", "Simon", NULL };
Run Code Online (Sandbox Code Playgroud)
std :: for_each在一个范围内"迭代",因此要将它与不确定长度的数组一起使用,您需要使用自定义迭代器来指示数组的结尾(在NULL成员上).如果你坚持使用以NULL结尾的char*数组,你当然可以为它创建自己的for_each函数,例如:
template <typename Function>
void for_each_in_null_terminated_cstring_array(const char** array, Function f)
{
while (*array) {
f(*array);
array++;
}
}
const char *names[] = { "Bob", "Adam", "Simon", NULL };
for_each_in_null_terminated_cstring_array(names, func);
Run Code Online (Sandbox Code Playgroud)
不过,我并不是真的推荐这个解决方案.
编辑:是的,更普遍的是总是更美好,不是吗?
template <typename T, typename Function>
void for_each_in_null_terminated_array(T* array, Function f)
{
while (*array) {
f(*array);
array++;
}
}
Run Code Online (Sandbox Code Playgroud)
(这里是我之前提到的null终止("false"-terminated)迭代器的实现 - 根据下面的建议进行了一两次更改.它应该是一个真正的InputIterator)
template <class T>
class nt_iterator: public std::iterator<std::input_iterator_tag, T>
{
public:
typedef typename nt_iterator<T>::pointer pointer;
typedef typename nt_iterator<T>::value_type value_type;
nt_iterator(): p(), pte(true) {}
nt_iterator(pointer p_): p(p_), pte(!p_) {}
nt_iterator(const nt_iterator<T>& rhs): p(rhs.p), pte(rhs.pte) {}
nt_iterator<T>& operator++() {
++p;
if (!*p) pte = true; // once past-the-end, always past-the-end
return *this;
}
nt_iterator<T> operator++(int) {
nt_iterator n(*this);
operator++();
return n;
}
bool operator==(const nt_iterator<T>& rhs) {
return pte && rhs.pte || p == rhs.p;
}
bool operator!=(const nt_iterator<T>& rhs) {
return !(operator==(rhs));
}
value_type operator*() { return *p; }
private:
pointer p;
bool pte; // past-the-end flag
};
Run Code Online (Sandbox Code Playgroud)
它是如何使用的:
void print(const char* str);
int main()
{
const char* array[] = {"One", "Two", "Three", NULL, "Will you see this?"};
std::for_each(nt_iterator<const char*>(array),
nt_iterator<const char*>(),
print);
}
Run Code Online (Sandbox Code Playgroud)
它可能比循环版本慢一点,因为等价检查的数量增加 - 与例如打印文本相比,速度差异当然是微不足道的 - 但是应该注意到,这std::for_each并不会神奇地使循环更快(事实上,您可能会惊讶地看到您的编译器供应商如何定义函数 - 也就是说,如果您期望太多).