在这里,我声明了两个模板类: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;
在这里,我声明了一个模板函数接受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的编译器。
此错误给我带来了很多问题,该如何解决呢?
答案 0 :(得分:3)
鉴于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;
}
答案 1 :(得分:2)
首先,您创建一个shared_ptr
,名称为:
auto b = std::make_shared<B<std::string>>();
类型为std::shared_ptr<B<std::string>>
,并且
std::shared_ptr<A<std::string>> a = b;
类型为std::shared_ptr<A<std::string>>
...
但是,在功能参数中,您具有:
void proc(std::shared_ptr<A<T>> &a)
仅指向 A 的shared_ptr
,而不是 B ,因此显而易见, B < / strong>不会成为 A ...
解决方案是从函数定义中删除a
的 lvalue 引用,例如:
void proc(std::shared_ptr<A<T>> a)
因此,它没有引用 A ,并且可以在函数调用期间将 B 轻松转换为 A ... >
编辑::添加了说明...
说明:
还记得指针吗?来自 C ... 是,它们具有与引用相同的功能:
// Compilable both in C and C++...
int add(int a, int b, int * more_than_3) {
int const result = a + b;
if (result > 3)
*more_than_3 = 1;
return result;
}
是的,这些将在C语言中实现伪返回类型的功能。
// Compilable both in C and C++...
int main(void) {
int more_3;
int const res = add(2, 3, &more_3);
printf("Sum of 2 + 3 is %i\n", res);
if (more_3)
printf("Given two numbers' sum is more than 3");
}
这里,传递了一个额外的参数,该参数使用 address of一个变量(引用也做同样的事情,它们与引用它们的变量共享地址。 ... )
记住,引用和指针存储其中另一个变量的地址 ...
这可能就是为什么他们使 运算符(&
)的地址也充当 C ++ 中的引用的原因。 ..
也不需要,但是@songyuanyao在此处发布的答案有效,因为:
void proc(std::shared_ptr<A<T>> const &a)
使用常量引用,是常量表达式的引用,而不是变量,因此它没有它们是否不匹配(A
和B
)