首页 > 解决方案 > 类型推导失败:派生模板的 shared_ptr 到基模板作为函数参数

问题描述

这里我声明了两个模板类:A和B,B派生自A:

template<typename T>
class A {
public:
    int a;
    T t;
};

template<typename T>
class B : public A<T> {
public:
    int b;
};

我做了一个shared_ptr<B<T>>并将其分配给shared_ptr<A<T>>,没关系:

auto b = std::make_shared<B<std::string>>();
std::shared_ptr<A<std::string>> a = b;

这里我声明了一个模板函数 accept shared_ptr A<T>

template<typename T>
void proc(std::shared_ptr<A<T>> &a) {
    std::cout << a->a << std::endl;
}

它接受a作为参数,但拒绝b

proc<std::string>(a); // OK
proc<std::string>(b); // template argument deduction/substitution failed
                      // cannot convert 'b' (type 'std::shared_ptr<B<std::__cxx11::basic_string<char> > >') to type 'std::shared_ptr<A<std::__cxx11::basic_string<char> > >&'

我使用 g++ 作为 -std=c++11 的编译器。

这个错误给我带来了很多问题,我该如何优雅地解决这个问题?

标签: c++templatesshared-ptr

解决方案


给定proc<std::string>(b);,b需要转换为std::shared_ptr<A<std::string>>. std::shared_ptr<A<std::string>>这意味着将构建一个临时对象,然后将其传递给proc. 的参数类型proc是对非常量的左值引用,即std::shared_ptr<A<T>> &不能绑定到临时变量。

您可以将参数类型更改为对 const 的左值引用,这可以绑定到临时变量。例如

template<typename T>
void proc(const std::shared_ptr<A<T>> &a) {
//        ^^^^^
    std::cout << a->a << std::endl;
}

推荐阅读