简体   繁体   中英

C++: Can I use smart pointers with templates?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM