开发者

split a string using find_if

开发者 https://www.devze.com 2022-12-14 09:48 出处:网络
I found the following code in the book \"Accelerated C++\" (Chapter 6.1.1), but I can\'t compile it. The problem is with the find_if lines. I have the necessary includes (vector, string, algorithm, cc

I found the following code in the book "Accelerated C++" (Chapter 6.1.1), but I can't compile it. The problem is with the find_if lines. I have the necessary includes (vector, string, algorithm, cctype). Any idea?

Thanks, Jabba

bool space(char c) {
    return isspace(c);
}

bool not_space(char c) {
    return !isspace(c);
}

vector<string> split_v3(const string& str)
{
    typedef string::const_iterator i开发者_如何学运维ter;
    vector<string> ret;
    iter i, j;

    i = str.begin();
    while (i != str.end())
    {
        // ignore leading blanks
        i = find_if(i, str.end(), not_space);

        // find end of next word
        j = find_if(i, str.end(), space);

        // copy the characters in [i, j)
        if (i != str.end()) {
            ret.push_back(string(i, j));
        }
        i = j;
    }
    return ret;
}


Writing this in a more STL-like manner,

#include <algorithm>
#include <cctype>
#include <functional>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

using namespace std;

template<class P, class T>
void split(const string &str, P pred, T output) {
    for (string::const_iterator i, j = str.begin(), str_end = str.end();
            (i = find_if(j, str_end, not1(pred))) != str_end;)
        *output++ = string(i, j = find_if(i, str_end, pred));
}

int main() {
    string input;
    while (cin >> input) {
        vector<string> words;
        split(input, ptr_fun(::isspace), inserter(words, words.begin()));
        copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
    }
    return 0;
}


There is no problem in the code you posted. There is a very obvious problem with the real code you linked to: is_space and space are member functions, and they cannot be called without an instance of Split2. This requirement doesn't make sense, though, so at least you should make those functions static.

(Actually it doesn't make much sense for split_v3 to be a member function either. What does having a class called Split2 achieve over having just a free function - possibly in a namespace?)


As requested:

class SplitV2 {
 public:
  void foo();
 private:
  struct space { bool operator() (char c) { return isspace(c); } };
  struct not_space {
    Split2::space space;
    bool operator() (char c) { return !space(c); }
  };

Use them with std::find_if(it, it2, space()) or std::find_if(it, it2, not_space().
Notice that not_space has a default constructed space as a member variable. It may be not wise to construct space in every call to bool not_space::operator() but maybe the compiler could take care of this. If the syntax for overloading operator() confuses you and you would like to know more about using structs as Predicates you should have a look at operator overloading and some guidelines to the STL.


Off hand, I would say it should probably be

i = str.find_if( ...
j = str.find_if( ...
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号