指向模板接口的唯一指针
Unique pointer to template interface
为了简单起见,我将问题简化为简单的例子。我有基类:
template<typename T>
class Base {
virtual T getParameter(T&) = 0;
};
以及使用工厂方法返回其对象的派生类:
template<typename T>
class Der : public Base<T> {
public:
static std::unique_ptr<Der> getInstance() {
return std::make_unique<Der<std::string>>();
}
T getParameter(T& param) override {
return param;
}
};
现在我想使用包含接口的unique_ptr传递派生类的对象,即:
template<typename T>
void someFun(std::unique_ptr<Base<T>>&& ptr) {
//do sth with ptr
}
通过调用:
someFun(Der<std::string>::getInstance());
错误:
test.cpp:26:44: error: no matching function for call to ‘someFun(std::unique_ptr<Der<std::__cxx11::basic_string<char> >, std::default_delete<Der<std::__cxx11::basic_string<char> > > >)’
someFun(Der<std::string>::getInstance());
^
test.cpp:21:6: note: candidate: template<class T> void someFun(std::unique_ptr<Base<T> >&&)
void someFun(std::unique_ptr<Base<T>>&& ptr) {
^~~~~~~
test.cpp:21:6: note: template argument deduction/substitution failed:
test.cpp:26:44: note: mismatched types ‘Base<T>’ and ‘Der<std::__cxx11::basic_string<char> >’
someFun(Der<std::string>::getInstance());
我认为解决这个问题的最简单方法是在派生类型上制作T
的别名Base
模板,并使用它而不是依赖模板推导。
如果您害怕意外输入不相关的东西,您仍然可以使用std::is_base_of<>
强制执行从Base
继承。
#include <memory>
#include <typer_traits>
template<typename T>
class Base {
public:
using param_t = T;
virtual T getParameter(T&) = 0;
};
template<typename T>
class Der : public Base<T> {
public:
static std::unique_ptr<Der> getInstance() {
return std::make_unique<Der<std::string>>();
}
T getParameter(T& param) override {
return param;
}
};
template<typename DerivT>
void someFun(std::unique_ptr<DerivT> deriv_ptr) {
using T = typename DerivT::param_t;
// Just to be safe
static_assert(std::is_base_of<Base<T>, DerivT>::value, "");
// If you REALLY care about only having a base pointer:
std::unique_ptr<Base<T>> ptr(deriv_ptr.release());
//do stuff.
}
void foo() {
someFun(Der<std::string>::getInstance());
}
如果您真的想处理不同的someFun()
过载,您也可以用enable_if
来做一些事情。但是,我发现static_assert()
方式要干净得多,因此除非必要,否则我会使用它。
第一次我会回答我自己的问题,解决方案是将唯一的 ptr 返回给 Base 而不是派生类:
static std::unique_ptr<Base<T>> getInstance() {
return std::make_unique<Der<std::string>>();
}
以前我返回了static std::unique_ptr<Der>
,编译器假设我不想使用接口引用我的对象。也许它会帮助任何有同样问题的人。
相关文章:
- 何时在引用或唯一指针上使用移动语义
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- 如何更改唯一指针向量的可见性
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- C++尝试深度复制唯一指针时出现内存访问冲突
- 使用 RTTI 克隆唯一指针的向量
- 为什么我无法创建唯一指针
- 如何将唯一指针的 std::vector 转换为原始指针的 std::span?
- 将唯一指针的指针传递给采用双指针的函数
- 在什么情况下,需要共享智能指针而无法使用唯一指针?
- C++唯一指针的向量
- 对带有唯一指针的 std::thread 使用类成员函数时出现编译错误
- 指向基类的唯一指针
- 添加要映射的对象的唯一指针
- 智能指针(唯一指针)和引用
- 唯一指针是否在堆或堆栈上分配内存?
- 尝试设置唯一指针布尔数组的值时BAD_ACCESS错误
- 使用唯一指针调用函数会使我的程序崩溃
- 将唯一指针插入std::映射