templating the container and contained type

This is a discussion on templating the container and contained type within the C++ Programming forums, part of the General Programming Boards category; Code: template<typename T>class foo { T *t; }; template<template<typename conatinedType>class container,typename containedType>void func(container<containedType>& c) { c.size(); } int _tmain(int argc, ...

  1. #1
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839

    templating the container and contained type

    Code:
    template<typename T>class foo
    {
      T *t;
    };
    
    template<template<typename conatinedType>class container,typename containedType>void func(container<containedType>& c)
    {
      c.size();
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
      std::vector< foo<int> >v;
      func(v);
    	return 0;
    }
    Error 1 error C2039: 'size' : is not a member of 'std::_Container_base_aux_alloc_empty<_Alloc>' c:\users\mfowler\documents\visual studio 2008\projects\test\test\test.cpp 13
    what i'd like to do is make a function that can process different kinds of stl containers, provided that they provide the required API. e.g. i may need to use a vector at some point and a valarray later. this is the attempted implementation that seems to come closest to doing what i want, but it's obviously still failing.

    any ideas? thanks.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It's probably simpler like this:

    Code:
    template <class Container>
    void foo(const Container& c)
    {
        //contained type is:
        typename Container::value_type item;
    }
    STL containers provide a bunch of typedefs for similar purposes.
    Last edited by anon; 06-24-2009 at 08:05 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,549
    Why are you providing 2 containedType parameters?
    template<template<typename conatinedType>class container,typename containedType>void func(container<containedType>& c)
    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
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    Quote Originally Posted by Elysia View Post
    Why are you providing 2 containedType parameters?
    template<template<typename conatinedType>class container,typename containedType>void func(container<containedType>& c)
    because otherwise it gave me a syntax error :\

    like i said, i tried a bunch of different template declarations and this one seemed to be the closest to working.

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Your template pattern cannot match std::vector, since std::vector takes more than one template parameter. The others have defaults, but they do exist.

    Basically, your implementation limits you to container types which take precisely one template parameter. That's like, basically none of them.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    839
    aaaah good catch.

    i'm only concerned with a small subset of stl for now, so i think that will give me what i need. thx bb.

    my function signature actually looks like:

    Code:
    void function(vector< foo<int> >&v,foo<int>& f)
    {
    //...
    }
    i wanted to make it explicitly clear that the contained type of the vector should be the same as the other function arguments, but i suppose

    Code:
    template<class container,typename T>void function(container& v,foo<T>& f)
    {
    //...
    }
    is sufficiently explicit, plus it has the additional benefit of actually working.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    The big problem with template template parameters is that the argument you pass has to have exactly that many template parameters - defaults are not considered. (I believe this will be remedied by C++0x's template aliases, but I'm not entirely sure.)
    Now add to that the fact that the standard library may give all their templates any number of template parameters, as long as all those beyond the standard-specified set are defaulted. For example, instead of making their safe STL depend on a preprocessor macro that's giving ABI-concerned people nightmares without end, Microsoft could have implemented it like this:
    Code:
    template <typename _Ty, typename _Alloc = std::allocator<_Ty>, bool _Safe = _CRT_DEFAULT_SAFE_MODE>
    class vector ...
    This would have been perfectly conforming, but would break any program that expected std::vector to match a template template parameter with two parameters.
    Which is why there are no such programs, and template template parameters are in extreme disuse.

    Edit:
    i wanted to make it explicitly clear that the contained type of the vector should be the same as the other function arguments
    No problem:
    Code:
    template<class container, typename T>
    void function(container& v, typename container::value_type& f)
    {
    //...
    }
    And for heaven's sake, give your code a little space to breathe.
    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

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