【问题标题】:C++: Can I use smart pointers with templates?C++:我可以在模板中使用智能指针吗?
【发布时间】:2021-05-19 13:43:03
【问题描述】:

我有一个抽象基类distributions 和两个派生类continuous_distributiondiscrete_distribution。我有一个函数make_distribution 和一个unordered_map,它返回一个指向(连续)分布的智能指针,

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];
}

由于有两个派生类,我想知道是否有一种方法可以利用模板编写一个函数,该函数返回指向相应分布类型的指针。我尝试使用以下内容,

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];
}

但是,当调用这个函数时,

int main()
{
    std::tuple<std::string, float, float> TARGET{"cauchy", 1, 1};
    std::shared_ptr<continuous_distribution> target = make_distribution(TARGET);
}

我收到一个我不太明白的错误,

no instance of function template "make_distribution" matches the argument list -- argument types are: (std::tuple<std::string, float, float>)

【问题讨论】:

  • 如果你有一个抽象类,这意味着多态性,这意味着你应该使用指向该基本抽象类的指针,比如std::shared_ptr&lt;distribution&gt;
  • TARGET的定义是什么? PS:最小的可重复示例也很好。
  • 请发帖minimal reproducible example。错误很大程度上来自TARGET 是什么,不知道是什么我们无能为力
  • 顺便说一句,完整的错误消息应该包含该信息
  • @Daphne 就像 NathanOliver 说的那样,你真的应该让 make_distribution() return shared_ptr&lt;distribution&gt; 充分利用你的多态性,但是当你绝对需要访问派生类的成员时,你可以使用 static_pointer_cast or dynamic_pointer_cast基类中不存在。

标签: c++ templates shared-ptr smart-pointers


【解决方案1】:

模板参数只能从调用函数的参数中推导出来,不能从返回类型中推导出来。而且你的函数中没有任何参数依赖于模板参数,因此不匹配。

在您的情况下,您必须明确指定模板参数,它应该可以工作:

std::shared_ptr<continuous_distribution> target = make_distribution<continuous_distribution>(TARGET);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 2012-07-02
    • 2014-03-11
    • 1970-01-01
    相关资源
    最近更新 更多