基于unique_ptr参数指针类型的重载函数
Overloading function based on pointer type of unique_ptr parameter
我的印象是 unique_ptr
可以像普通指针一样推断出 class 层次结构,但是当我尝试重载这样的函数时:
void func(unique_ptr<Derived1>& d1);
void func(unique_ptr<Derived2>& d2);
然后像这样调用其中一个函数:
unique_ptr<Base> b = make_unique<Derived1>();
func(b);
我收到一条错误消息说 no instance of overloaded function "func" matches the argument list
。 b 的运行时类型是 Derived1
,所以我预计会调用第一个重载。
此外,当我从函数 return 一个 unique_ptr
时,编译器能够将派生的 class 转换为(?不确定适当的术语)到基 class,所以像这样的东西可以工作:
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
通常在我的代码中,我将变量声明为这样的函数的结果。它们被声明为基础但具有派生的运行时类型,我想将它们传递到一个重载函数中。
如何以与涉及 class 层次结构的常规指针相同的方式重载函数?
你是对的,所有标准智能指针的隐式转换操作都模仿原始指针的隐式转换操作。这允许编译第二个片段,即
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
但是,对于第一个代码片段存在误解,因为从来没有从基 class 到派生 class 的内置隐式类似向下转换的转换。使用普通指针,
void func(Derived1* d1);
void func(Derived2* d2);
Base* b = new Derived1();
func(b);
也不会编译。这在基本的 OOP 意义上是有意义的——通过基础 class 接口查看继承层次结构中的对象,并隐藏实际的具体运行时类型。
如果您需要这种调度的设计,您需要阅读“访问者”设计模式,它实现了一种称为双重(或多重)调度的技术。但是实现这一点所需的样板数量会提示您为什么该语言不提供这种内置的调度。
我的印象是 unique_ptr
可以像普通指针一样推断出 class 层次结构,但是当我尝试重载这样的函数时:
void func(unique_ptr<Derived1>& d1);
void func(unique_ptr<Derived2>& d2);
然后像这样调用其中一个函数:
unique_ptr<Base> b = make_unique<Derived1>();
func(b);
我收到一条错误消息说 no instance of overloaded function "func" matches the argument list
。 b 的运行时类型是 Derived1
,所以我预计会调用第一个重载。
此外,当我从函数 return 一个 unique_ptr
时,编译器能够将派生的 class 转换为(?不确定适当的术语)到基 class,所以像这样的东西可以工作:
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
通常在我的代码中,我将变量声明为这样的函数的结果。它们被声明为基础但具有派生的运行时类型,我想将它们传递到一个重载函数中。
如何以与涉及 class 层次结构的常规指针相同的方式重载函数?
你是对的,所有标准智能指针的隐式转换操作都模仿原始指针的隐式转换操作。这允许编译第二个片段,即
unique_ptr<Base> create(){
return make_unique<Derived1>();
}
但是,对于第一个代码片段存在误解,因为从来没有从基 class 到派生 class 的内置隐式类似向下转换的转换。使用普通指针,
void func(Derived1* d1);
void func(Derived2* d2);
Base* b = new Derived1();
func(b);
也不会编译。这在基本的 OOP 意义上是有意义的——通过基础 class 接口查看继承层次结构中的对象,并隐藏实际的具体运行时类型。
如果您需要这种调度的设计,您需要阅读“访问者”设计模式,它实现了一种称为双重(或多重)调度的技术。但是实现这一点所需的样板数量会提示您为什么该语言不提供这种内置的调度。