Thread: iterator to unspecified container?

  1. #1
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168

    iterator to unspecified container?

    If you have a template with two template arguments, one for the underlying type, and the other being a container of the underlying type, how can you get an iterator to an unspecified container?

    Code:
    
    template<typename T, typename K>
    class Foo{
    
        K container;
    
        public:
    
            Foo(const K& container){
    
                // get iterator to 'k'
    
                // copy 'T' elements from 'k'
            }
    };
    
    int main(){
    
        std::vector<int> vec;
        Foo<int, std::vector<int> > foo_vec(vec);
    
        std::list<int> list;
        Foo<int, std::list<int> > foo_list(list);
    
        return 0;
    }
    goto( comeFrom() );

  2. #2
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    As a design co sideration, would it be better to implement a range copy in a constructor accepting iterators to the external container thus eliminating the need for the second template argument?

    Opinions?
    goto( comeFrom() );

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    As for the first question, you would just do
    Code:
    typename K::iterator
    Now, normally you don't need the "underlying" type. First off, you probably won't use it. Secondly, there are typedefs wrapped inside the containers that contains the type they encapsulate 99% of the cases (can't remember what exactly they're called, though).
    Better yet, in C++0x, you should be able to do...
    Code:
    decltype(*K.begin())
    ...to get the encapsulated type (or the like).

    As for the second question, I assume that you want to copy all the elements from container to this->container?
    Then you don't need to know T. All you need to do is:
    Code:
    std::copy(container.begin(), container.end(), std::back_inserter(this->container));
    (Assuming your container supports the push_back method.)
    Last edited by Elysia; 06-03-2010 at 10:03 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Quote Originally Posted by Elysia View Post
    As for the first question, you would just do
    Code:
    typename K::iterator
    Now, normally you don't need the "underlying" type. First off, you probably won't use it. Secondly, there are typedefs wrapped inside the containers that contains the type they encapsulate 99% of the cases (can't remember what exactly they're called, though).
    Better yet, in C++0x, you should be able to do...
    Code:
    decltype(*K.begin())
    ...to get the encapsulated type (or the like).
    I swear "typename" is like the magic band-aid word in C++ templates -apply it, and all is well...

    Thank you.

    The reason I need T, is I will be copying T values into wrapper objects that contains members of type T and a pointer to an iterator of type K<T>, then added to a private container K<T>. The idea is to provide instant access to objects of type T, in any iterateable container, in other containers with the same elements, just sorted differently.

    I know, I know, boost::multi_index_container does indeed provide this exact end-functionality, I'm just trying to implement something similar for my own practice. I desperately need the template practice.

    Of course, I am always open to any suggestions, and opinions, and if any of you c++ wizards on this forum can steer me in a better direction, I'll be very happy to listen.
    goto( comeFrom() );

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    STL containers define typedef's for the underlying type and iterators, so you really just need the container as a template parameter. Also, they can be initialized and assigned via their copy-constructor and assignment operator, respectively.

    Code:
    template<typename K>
    class Foo{
    
        typedef typename K::value_type value_type;
        typedef typename K::iterator iterator;
        typedef typename K::const_iterator const_iterator;
        
        K container;
    
        public:
    
            Foo(const K& container)
            : container(container) {
            }        
    };
    
    int main(){
    
        std::vector<int> vec;
        Foo<std::vector<int> > foo_vec(vec);
    
        std::list<int> list;
        Foo<std::list<int> > foo_list(list);
    
        return 0;
    }
    **edit**

    Another thing you can do in this kind of situation is to make the constructor a template function, so as to accept any arbitrary container type, eg:

    Code:
    	template< typename Other >
            Foo( const Other& rhs )
    	: container( rhs.begin( ), rhs.end( ) ) {
            }
    Last edited by Sebastiani; 06-03-2010 at 11:50 AM.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    To make Sebastiani's example a little more fancy with lovely C++0x functionality:
    Code:
    template<typename K>
    class Foo
    {
        typedef typename K::iterator iterator;
        typedef typename K::const_iterator const_iterator;
        
        K container;
    
        public:
    
            Foo(const K& container)
            : container(container) 
            {
                typedef decltype(*container.begin()) value_type;
            }        
    };
    
    int main()
    {
        // No space between ">>" needed in C++0x.
        std::vector<int> vec;
        Foo<std::vector<int>> foo_vec(vec);
    
        std::list<int> list;
        Foo<std::list<int>> foo_list(list);
    
        return 0;
    }
    And I'll also tell you a remember rule for typename. So long as you are using a dependent type, you must use typename. A dependent type is a type which relies on some unknown type T. To know WTH I'm talking about, here are some examples:
    Code:
    template<typename T> struct bar { typedef int myint; };
    
    template<typename T>
    void foo()
    {
        int MyVar1; // Not a dependent name. Obviously.
        typename bar<T>::myint MyVar2; // Dependant name, because we are accessing myint inside bar which depends on T which is unknown.
        bar<int>::myint MyVar3; // Not a dependent name because int is a known type.
        typename std::vector<T>::iterator MyIt1; // Dependent name because T is unknown.
        std::vector<char>::iterator MyIt2; // Not dependent name because char is a known type.
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Not sure, but doesn't C++0x have also "auto" keyword for these things?

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It does, if you try to assign something to a variable. There are some situations where auto cannot help. Try iterating a vector by indices with auto.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Thank you all for the helpful replies!

    @ Elysia

    I guess I never even wondered what exactly *typename* was used for until I ran into this situation. Now it seems so clear. Thank you.

    I'm not sure if I'm using C++0x, what version of gcc would that be (i.e. x.x.x whatever)?
    I've been using for_each but my compiler still b*tches about the space between > > So i'm not really sure.

    My available compilers are whatever gcc version came with Code::Blocks 10.5, I have Visual Studio Pro 2008, and gcc 3.4.4 via cygwin
    goto( comeFrom() );

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well, compile this snippet:
    Code:
    int main() { auto i = 0; }
    Does it compile? Then your compiler supports C++0x.
    From what I understand, Code::Blocks 10.05 (the newest) has a GCC 4.4.x version which should support C++0x. But I am not exactly keeping myself up-to-date on GCC. It might also be that GCC doesn't support the ">>" syntax. Yet.
    Visual Studio 2010 has C++0x support. 2008 does not.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Visual Studio 2010 has C++0x support.
    O_o

    Visual Studio 2010 has some C++0x support.
    Fixed.

    Soma

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Heh. My bad.
    There is no full C++0x support anywhere since it's... well, not finished.
    GCC has some C++0x support, too.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    No dice. But wait... I lied, I have Code::Blocks 8.02. Time for a quick upgrade.
    goto( comeFrom() );

  14. #14
    ...and never returned. StainedBlue's Avatar
    Join Date
    Aug 2009
    Posts
    168
    Didn't compile with Code::Blocks 10.05, although this helpful message was displayed:

    C:\Projects\_CPP\cpp0102\main.cpp|1|warning: 'auto' will change meaning in C++0x; please remove it|
    I guess they're working on it?
    goto( comeFrom() );

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    *shrug* I guess someone with the proper knowledge will have to step in. I don't know anything about GCC or C::B.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting container
    By l2u in forum C++ Programming
    Replies: 6
    Last Post: 09-01-2007, 01:12 PM
  2. stl container to store more than 1 type
    By sujeet1 in forum C++ Programming
    Replies: 7
    Last Post: 05-09-2007, 04:10 AM
  3. Replies: 1
    Last Post: 01-23-2006, 07:12 PM
  4. Linked List Queue Implementation help
    By Kenogu Labz in forum C++ Programming
    Replies: 8
    Last Post: 09-21-2005, 10:14 AM
  5. undefined vs. unspecified (C++ standard)
    By Sang-drax in forum C++ Programming
    Replies: 7
    Last Post: 11-12-2002, 11:51 AM