Use the template parameter to take a decission without specialization

A

Arkaitz Jimenez

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
 
A

Aaron Graham

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 said:
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.
...
};
 
A

Arkaitz Jimenez

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>,


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.
  ...

};

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
 
N

Noah Roberts

Arkaitz said:
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.
 
A

Arkaitz Jimenez

Ideally I'd like it to work for any type without needing to create the
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
 
M

Michael DOUBEZ

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;
 
T

Thomas J. Gritzan

Arkaitz said:
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).
 
N

Noah Roberts

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top