Return *any* container

This is a discussion on Return *any* container within the C++ Programming forums, part of the General Programming Boards category; 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, ...

  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
    21,409
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    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
    21,409
    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.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    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,893
    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, 12:54 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21