Assume I receive two arguments to a template, T1 and T2. If I know T1 is itself a templated class (e.g., a container), and T2 can be anything, is it possible for me to determine the base template type for T1 and rebuild it using T2 as its argument?
For example, if I receive std::vector<int>
and std::string
, I would want to automatically build std::vector<std::string>
. However if I were given std::set<bool>
and double
, it would produce std::set<double>
.
After reviewing type_traits, relevant blogs, and other questions here, I don't see a general approach to solving this problem. The only way I can currently see to accomplish this task is to build template adapters for each type that could be passed in as T1.
For example, if I had:
template<typename T_inner, typename T_new>
std::list<T_new> AdaptTemplate(std::list<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::set<T_new> AdaptTemplate(std::set<T_inner>, T_new);
template<typename T_inner, typename T_new>
std::vector<T_new> AdaptTemplate(std::vector<T_inner>, T_new);
I should be able to use decltype and rely on operator overloading to solve my problem. Something along the lines of:
template <typename T1, typename T2>
void MyTemplatedFunction() {
using my_type = decltype(AdaptTemplate(T1(),T2()));
}
Am I missing something? Is there a better approach?
WHY do I want to do this?
I'm building a C++ library where I want to simplify what users need to do to build modular templates. For example, if a user wants to build an agent-based simulation, they might configure a World template with an organism type, a population manager, an environment manager, and a systematics manager.
Each of the managers also need to know the organism type, so a declaration might look something like:
World< NeuralNetworkAgent, EAPop<NeuralNetworkAgent>,
MazeEnvironment<NeuralNetworkAgent>,
LineageTracker<NeuralNetworkAgent> > world;
I'd much rather users not have to repeat NeuralNetworkAgent
each time. If I am able to change template arguments, then default arguments can be used and the above can be simplified to:
World< NeuralNetworkAgent, EAPop<>, MazeEnvironment<>, LineageTracker<> > world;
Plus it's easier to convert from one world type to another without worrying about type errors.
Of course, I can deal with most errors using static_assert and just deal with the longer declarations, but I'd like to know if a better solution is possible.