Thread: Return *any* container

  1. #1
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217

    Return *any* container

    I was just converting a function from

    bool SaveStringList(const std::vector<std::string>& strList, const std::string& fileName)

    to

    template<class InputIterator>
    bool SaveStringList(InputIterator first, InputIterator last, const std::string& fileName)

    so it can take any container type. I wanted to do the same with
    std::vector<std::string> LoadStringList(const std::string& fileName)

    Where it returns any container type. Anyone know a way i can do this?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Instead of returning a container, take an iterator to the start of a range. Iterator adapters like back_inserter() can then be used to add elements to a container via an iterator to its first element.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Hmmm, i'm new to iterators but i'm assuming that would look like this..?:

    Code:
    std::vector<std::string> strList;
    LoadStringList(strList.begin(), "somefile.txt");
    Is there anyway i can have it like this:

    Code:
    std::vector<std::string> strList = LoadStringList("somefile.txt");
    or
    Code:
    std::vector<std::string> strList = LoadStringList<std::vector>("somefile.txt");

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Hmmm, i'm new to iterators but i'm assuming that would look like this..?
    Yes, but if you do not use an iterator adapter, it implies that your container already has as many elements as is needed.

    Is there anyway i can have it like this:
    Yes, you could do the latter, e.g.,
    Code:
    template<class T>
    T LoadStringList(const std::string& fileName)
    {
        T container;
        // ...
        return container;
    }
    You cannot use the former since the template argument cannot be deduced from the function template argument.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Ok thanks i've gone with your way. Is this how it should look?

    Code:
    template <class T>
    bool LoadStringList(T& strList, const std::string& fileName)
    {
        char line[0xFFFF];
        std::back_insert_iterator<T> it = back_inserter(strList);
        ...
    }
    
    std::vector<std::string> strList;
    LoadStringList(strList, "somefile.txt");
    Last edited by 39ster; 08-18-2008 at 12:28 AM.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Hmmm ok i have a new problem. This "back_inserter" method doesn't work on the container std::set. It says there is no member named push_back (which i assume back_insert:perator=() calls).

    BTW: Is std::set the correct container to use? The container i need has to store unique strings. I don't want it to add a new string if the string already exists.
    Last edited by 39ster; 08-18-2008 at 12:58 AM.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by 39ster View Post
    Ok thanks i've gone with your way. Is this how it should look?
    No, the function should take the iterator as an argument, not the container. As you've seen, you otherwise run into problems with std::set.

    Code:
    template <typename Iter>
    void LoadStringList(Iter it, const std::string &filename)
    {
      // ...
      *it = str;
      ++it;
      // ...
    }
    
    void into_vector()
    {
      std::vector<std::string> v;
      LoadStringList(std::back_inserter(v), filename);
    }
    
    void into_set()
    {
      std::set<std::string> s;
      LoadStringList(std::inserter(s), filename);
    }
    I'm not 100% sure about the name of the insertion iterator that works with std::set.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. is it ok like that?
    By ExDHaos in forum C++ Programming
    Replies: 8
    Last Post: 05-23-2009, 09:02 AM
  2. How can I make this code more elegant?
    By ejohns85 in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2009, 08:55 AM
  3. need help program crashing
    By tunerfreak in forum C++ Programming
    Replies: 14
    Last Post: 05-22-2006, 11:29 AM
  4. opengl help
    By heat511 in forum Game Programming
    Replies: 4
    Last Post: 04-05-2004, 01:08 AM
  5. Algorithm to walk through a maze.
    By Nutshell in forum C Programming
    Replies: 30
    Last Post: 01-21-2002, 01:54 AM