I have an abstract base class distributions
with two derived classes, continuous_distribution
and discrete_distribution
. I have a function make_distribution
with an unordered_map
that returns a smart pointer to a (continuous) distribution,
std::shared_ptr<continuous_distribution> make_distribution(std::tuple<std::string, float, float> DIST)
{
std::string name = std::get<0>(DIST);
float a = std::get<1>(DIST);
float b = std::get<2>(DIST);
std::unordered_map<std::string,std::shared_ptr<continuous_distribution>> MAP = {
std::make_pair("cauchy", std::make_shared<cauchy>(a, b)),
std::make_pair("exponential", std::make_shared<exponential>(a)),
{...}
};
return MAP[name];
}
Because of the two derived classes, I was wondering if there is a way to make use of a template to write a single function that returns a pointer to the respective type of distribution. I tried using the following,
template <class type>
std::shared_ptr<type> make_distribution(std::tuple<std::string, float, float> DIST)
{
std::string name = std::get<0>(DIST);
float a = std::get<1>(DIST);
float b = std::get<2>(DIST);
std::unordered_map<std::string,std::shared_ptr<type>> MAP = {
std::make_pair("cauchy", std::make_shared<cauchy>(a, b)),
std::make_pair("exponential", std::make_shared<exponential>(a)),
{...}
};
return MAP[name];
}
However, when calling this function,
int main()
{
std::tuple<std::string, float, float> TARGET{"cauchy", 1, 1};
std::shared_ptr<continuous_distribution> target = make_distribution(TARGET);
}
I get an error that I don't quite understand,
no instance of function template "make_distribution" matches the argument list -- argument types are: (std::tuple<std::string, float, float>)
Template parameters can only be deduced from the calling function parameters, they are NOT deduced from the return type. And none of the parameters in your function depend on template parameters, hence no match.
In your case you have to specify template parameter EXPLICITLY and it should work:
std::shared_ptr<continuous_distribution> target = make_distribution<continuous_distribution>(TARGET);