c++ - dynamic_cast 从非模板类到模板子类
问题描述
我有一个非模板类 NC 和一个派生模板类 TC。我想将指向 NC 的指针(可能是指向 TC 实例的指针)转换为 TC 指针。模板的实际类型仅限于例如 bool、int 和 string。
class NC {
...
}
template <typename T>
class TC: public NC {
private:
T value;
public:
...
void setValue(T value) {
this->value = value;
}
}
class UserValueProvider {
public:
int getValue() const { return 5; }
bool getValue() const { return true; }
string getValue() const { return "foobar"; }
}
void setUserValue(UserValueProvider *uvp, NC *obj) {
auto tobj = dynamic_cast< ? >(obj); // what goes here?
if(tobj)
tobj->setValue(uvp->getValue());
}
显而易见的解决方案是执行 3 次动态转换(对于 int、bool 和 string)并调用专用实例的 setValue。然而我想知道是否可能有另一种解决方案,因为可能的专业化越多,需要的动态演员表就越多,而且它更有可能忘记一个专业化。
解决方案
这里的一种解决方案是翻转调用,并使用虚函数。但首先,让我们重写UserValueProvider::getValue
,因为仅对返回类型进行重载是被禁止的。
class UserValueProvider {
template <class T> struct tag { };
int getValue(tag<int>) const { return 5; }
bool getValue(tag<bool>) const { return true; }
std::string getValue(tag<std::string>) const { return "foobar"; }
public:
template <class T>
T getValue() const {
return getValue(tag<T>{});
}
};
现在我们可以调用uvp.getValue<T>()
来获取对应的值了。NC
接下来,向及其派生类添加一个虚函数:
class NC {
public:
virtual void setValueFrom(UserValueProvider &uvp) = 0;
};
template <typename T>
class TC: public NC {
private:
T value;
public:
void setValue(T value) {
this->value = value;
}
void setValueFrom(UserValueProvider &uvp) override {
setValue(uvp.getValue<T>());
}
};
瞧,您可以将您的类型传递UserValueProvider
给您的类型擦除NC
,它会正确调度。
void setUserValue(UserValueProvider *uvp, NC *obj) {
obj->setValueFrom(*uvp);
}
推荐阅读
- docker - 将 Docker 与官方 Progress OpenEdge RDBMS 映像一起使用
- regex - Regex a portion of string with a specific patten
- java - 我如何正确准备 JDBC PreparedStatment?
- ios - 如何在 NativeScript 7 中使用原生 SwiftUI 视图
- python - 加密 PEP 517 错误 ask-sdk-webservice-support
- javascript - 输入一个字母时,搜索栏不显示所有相关结果
- permissions - 如何使用 graphene-django 限制谁可以访问 GraphiQL API 浏览器?
- reactjs - 在域的 nginx 服务器上显示反应应用程序时出现问题
- python - GCP Dataflow + Apache Beam - 缓存问题
- javascript - 在 React Js 中重新渲染画布