Use the template parameter to take a decission without specialization

Discussion in 'C++' started by Arkaitz Jimenez, Apr 22, 2009.

  1. Hi,

    Is there any way that I could do something in a template based in the
    template name?
    Say that function<T> wants to put all received objects T in their
    corresponding, per type, collection object. I know that in template
    instantiation time we already have the information required, but I
    can't figure out a way of doing it.

    Any hint?

    Thanks

    Arkaitz
     
    Arkaitz Jimenez, Apr 22, 2009
    #1
    1. Advertising

  2. Arkaitz Jimenez

    Aaron Graham Guest

    Re: Use the template parameter to take a decission withoutspecialization

    Your description is very vague, but you may be able to use
    boost::mpl::map.

    #include <boost/mpl/at.hpp>
    #include <boost/mpl/map.hpp>

    namespace mpl = boost::mpl;
    typedef mpl::map<
    mpl::pair<TypeA, CollectionTypeA>,
    mpl::pair<TypeB, CollectionTypeB>,
    mpl::pair<TypeC, CollectionTypeC>
    > collection_map;


    template <typename T>
    struct collator {
    ...
    typedef typename mpl::at<collection_map, T>::type collection_type;
    // So if T is TypeA, then collection_type is CollectionTypeA, etc.
    ...
    };


    On Apr 22, 8:01 am, Arkaitz Jimenez <> wrote:
    > Hi,
    >
    > Is there any way that I could do something in a template based in the
    > template name?
    > Say that function<T> wants to put all received objects T in their
    > corresponding, per type, collection object. I know that in template
    > instantiation time we already have the information required, but I
    > can't figure out a way of doing it.
    >
    > Any hint?
    >
    > Thanks
    >
    > Arkaitz
     
    Aaron Graham, Apr 22, 2009
    #2
    1. Advertising

  3. Re: Use the template parameter to take a decission withoutspecialization

    On Apr 22, 5:27 pm, Aaron Graham <> wrote:
    > Your description is very vague, but you may be able to use
    > boost::mpl::map.
    >
    > #include <boost/mpl/at.hpp>
    > #include <boost/mpl/map.hpp>
    >
    > namespace mpl = boost::mpl;
    > typedef mpl::map<
    >   mpl::pair<TypeA, CollectionTypeA>,
    >   mpl::pair<TypeB, CollectionTypeB>,
    >   mpl::pair<TypeC, CollectionTypeC>
    >
    > > collection_map;

    >
    > template <typename T>
    > struct collator {
    >   ...
    >   typedef typename mpl::at<collection_map, T>::type collection_type;
    >   // So if T is TypeA, then collection_type is CollectionTypeA, etc.
    >   ...
    >
    > };
    >
    > On Apr 22, 8:01 am, Arkaitz Jimenez <> wrote:
    >
    > > Hi,

    >
    > > Is there any way that I could do something in a template based in the
    > > template name?
    > > Say that function<T> wants to put all received objects T in their
    > > corresponding, per type, collection object. I know that in template
    > > instantiation time we already have the information required, but I
    > > can't figure out a way of doing it.

    >
    > > Any hint?

    >
    > > Thanks

    >
    > > Arkaitz

    >
    >


    Hi,
    Thanks but I don't think that could help me.

    Ideally I'd like it to work for any type without needing to create the
    containers beforehand(may be adding dynamically containers to a static
    container when the first object of that type comes).

    But even If not, I'd have
    static container<int> intcontainer;
    static container<myclass> myclasscontainer;

    template<T>
    void Storeme<T>(T object){
    /*How can I use here the info I have about T to choose the proper
    container, in compile time, no RTTI*/
    }

    I'm not sure if it's doable.

    Thanks

    Arkaitz
     
    Arkaitz Jimenez, Apr 22, 2009
    #3
  4. Arkaitz Jimenez

    Noah Roberts Guest

    Re: Use the template parameter to take a decission without specialization

    Arkaitz Jimenez wrote:
    > On Apr 22, 5:27 pm, Aaron Graham <> wrote:
    >> Your description is very vague, but you may be able to use
    >> boost::mpl::map.
    >>
    >> #include <boost/mpl/at.hpp>
    >> #include <boost/mpl/map.hpp>
    >>
    >> namespace mpl = boost::mpl;
    >> typedef mpl::map<
    >> mpl::pair<TypeA, CollectionTypeA>,
    >> mpl::pair<TypeB, CollectionTypeB>,
    >> mpl::pair<TypeC, CollectionTypeC>
    >>
    >>> collection_map;

    >> template <typename T>
    >> struct collator {
    >> ...
    >> typedef typename mpl::at<collection_map, T>::type collection_type;
    >> // So if T is TypeA, then collection_type is CollectionTypeA, etc.
    >> ...
    >>
    >> };
    >>
    >> On Apr 22, 8:01 am, Arkaitz Jimenez <> wrote:
    >>
    >>> Hi,
    >>> Is there any way that I could do something in a template based in the
    >>> template name?
    >>> Say that function<T> wants to put all received objects T in their
    >>> corresponding, per type, collection object. I know that in template
    >>> instantiation time we already have the information required, but I
    >>> can't figure out a way of doing it.
    >>> Any hint?
    >>> Thanks
    >>> Arkaitz

    >>

    >
    > Hi,
    > Thanks but I don't think that could help me.
    >
    > Ideally I'd like it to work for any type without needing to create the
    > containers beforehand(may be adding dynamically containers to a static
    > container when the first object of that type comes).
    >
    > But even If not, I'd have
    > static container<int> intcontainer;
    > static container<myclass> myclasscontainer;
    >
    > template<T>
    > void Storeme<T>(T object){
    > /*How can I use here the info I have about T to choose the proper
    > container, in compile time, no RTTI*/
    > }


    template < typename T >
    struct container_container
    {
    static container<T> the_container;
    };

    template < typename T >
    container<T> container_container<T>::the_container;

    template < typename T >
    void store(T const& object)
    {
    container_container<T>::the_container.push_back(object);
    }

    Untested.
     
    Noah Roberts, Apr 22, 2009
    #4
  5. Re: Use the template parameter to take a decission withoutspecialization

    > > Ideally I'd like it to work for any type without needing to create the
    > > containers beforehand(may be adding dynamically containers to a static
    > > container when the first object of that type comes).

    >
    > > But even If not, I'd have
    > > static container<int> intcontainer;
    > > static container<myclass> myclasscontainer;

    >
    > > template<T>
    > > void Storeme<T>(T object){
    > > /*How can I use here the info I have about T  to choose the proper
    > > container, in compile time, no RTTI*/
    > > }

    >
    > template < typename T >
    > struct container_container
    > {
    >    static container<T> the_container;
    >
    > };
    >
    > template < typename T >
    > container<T> container_container<T>::the_container;
    >
    > template < typename T >
    > void store(T const& object)
    > {
    >    container_container<T>::the_container.push_back(object);
    >
    > }
    >
    > Untested.


    Hi, I've tried this code,
    apparently the Test::get<int> is being instantiated properly but not
    the mapper<int> that is required inside of Test::get<int>, I'd expect
    it to know that it needs that other template there.

    template < typename T >
    struct mapper
    {
    static std::map<char*,T> tmap;

    };

    class Test{
    public:
    template<typename T>
    Safe<T> get(char *name){
    return mapper::tmap[name];
    }
    };
    Error:
    undefined reference to `mapper<int>::tmap'

    Any hint?

    Thanks

    Arkaitz
     
    Arkaitz Jimenez, Apr 23, 2009
    #5
  6. Re: Use the template parameter to take a decission without specialization

    Arkaitz Jimenez wrote:
    [snip]
    > Hi, I've tried this code,
    > apparently the Test::get<int> is being instantiated properly but not
    > the mapper<int> that is required inside of Test::get<int>, I'd expect
    > it to know that it needs that other template there.
    >
    > template < typename T >
    > struct mapper
    > {
    > static std::map<char*,T> tmap;
    >
    > };
    >
    > class Test{
    > public:
    > template<typename T>
    > Safe<T> get(char *name){
    > return mapper::tmap[name];
    > }
    > };
    > Error:
    > undefined reference to `mapper<int>::tmap'
    >
    > Any hint?


    Add somewhere:

    template < typename T >
    std::map<char*,T> mapper<T>::tmap;


    --
    Michael
     
    Michael DOUBEZ, Apr 23, 2009
    #6
  7. Re: Use the template parameter to take a decission without specialization

    Arkaitz Jimenez schrieb:
    > Hi, I've tried this code,
    > apparently the Test::get<int> is being instantiated properly but not
    > the mapper<int> that is required inside of Test::get<int>, I'd expect
    > it to know that it needs that other template there.
    >
    > template < typename T >
    > struct mapper
    > {
    > static std::map<char*,T> tmap;


    But you do know, that it's not a good idea to use char* as a key into a
    map? This will only work when all identical strings have the same
    address. When they don't, use a std::string as key instead.

    >
    > };
    >
    > class Test{
    > public:
    > template<typename T>
    > Safe<T> get(char *name){
    > return mapper::tmap[name];
    > }
    > };
    > Error:
    > undefined reference to `mapper<int>::tmap'


    You need to define static members somewhere in an implementation file
    (not a header).

    --
    Thomas
     
    Thomas J. Gritzan, Apr 23, 2009
    #7
  8. Arkaitz Jimenez

    Noah Roberts Guest

    Re: Use the template parameter to take a decission without specialization

    Arkaitz Jimenez wrote:
    >>> Ideally I'd like it to work for any type without needing to create the
    >>> containers beforehand(may be adding dynamically containers to a static
    >>> container when the first object of that type comes).
    >>> But even If not, I'd have
    >>> static container<int> intcontainer;
    >>> static container<myclass> myclasscontainer;
    >>> template<T>
    >>> void Storeme<T>(T object){
    >>> /*How can I use here the info I have about T to choose the proper
    >>> container, in compile time, no RTTI*/
    >>> }

    >> template < typename T >
    >> struct container_container
    >> {
    >> static container<T> the_container;
    >>
    >> };
    >>
    >> template < typename T >
    >> container<T> container_container<T>::the_container; // <<<
    >>
    >> template < typename T >
    >> void store(T const& object)
    >> {
    >> container_container<T>::the_container.push_back(object);
    >>
    >> }


    > template < typename T >
    > struct mapper
    > {
    > static std::map<char*,T> tmap;
    >
    > };
    >
    > class Test{
    > public:
    > template<typename T>
    > Safe<T> get(char *name){
    > return mapper::tmap[name];
    > }
    > };
    > Error:
    > undefined reference to `mapper<int>::tmap'
    >
    > Any hint?


    Yeah, look at the code I provided more closely. What you've written is
    not equivalent.
     
    Noah Roberts, Apr 23, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joseph Turian
    Replies:
    1
    Views:
    298
    Victor Bazarov
    Jan 5, 2006
  2. Joseph Turian
    Replies:
    2
    Views:
    486
  3. mliptak
    Replies:
    3
    Views:
    353
    mliptak
    Mar 21, 2007
  4. Stuart Redmann
    Replies:
    5
    Views:
    507
    Stuart Redmann
    Dec 14, 2007
  5. flopbucket
    Replies:
    5
    Views:
    520
    Greg Herlihy
    May 15, 2008
Loading...

Share This Page