在c++中检查运行时的可转换性
Checking for convertability at runtime in c++
在c++中,不同类型的转换是隐式完成的。例如,类型为int
的对象可以分配给const int
(如下面代码中主函数的第一行中所做的)。
现在,我想在运行时检查可转换性,因为我有一个可以添加类型的结构,稍后如果存储在该结构中的类型之一可以转换为给定类型,我想检查给定类型。
以下是我到目前为止的想法:
#include <iostream>
#include <vector>
struct bar { virtual void dummy() {} };
template<typename T> struct foo : public bar { virtual void dummy() {} };
int main() {
int i1 = 1;
const int i2 = i1;
std::vector<bar*> bars;
bar* t1 = new foo<int>; bars.push_back(t1);
bar* t2 = new foo<int const>; bars.push_back(t2);
foo<int const>* t3 = dynamic_cast<foo<int const>*>(bars[0]);
std::cout << t3 << std::endl;
foo<int const>* t4 = dynamic_cast<foo<int const>*>(bars[1]);
std::cout << t4 << std::endl;
delete t1;
delete t2;
return 0;
}
为了在结构中存储类型,我创建了从bar
派生的模板结构foo
。然后,我可以将不同类型的int
和int const
(精确地说是指向foo<int>
和foo<int const>
类型的对象的指针)存储在bar*
s的向量中。然后,对于给定类型(此处为int const
),我检查该向量中的每个元素是否可以动态地广播到具有该类型的foo
。
当运行此代码时,t3
变为nullptr
,t4
变为非空指针。但我希望t3
也有一个非空指针。
我希望我想做的事情大致清楚。
你有什么想法吗?如何在运行时实现这种兼容性检查(一个涉及c++11功能的解决方案完全可以)?
不幸的是,由于foo<int>
和foo<const int>
是完全不相关的类型,您无法轻松做到这一点。
bar* t1 = new foo<int>;
foo<int const>* t3 = ?????<foo<int const>*>(t1);
t3
不能是指向t1
任何部分的指针,因为t1
既不是也不包含t3
指向的foo<int const>
。从中获得任何良好行为的唯一方法是将t1
保存的数据复制到全新的foo<int const>*
中。这种令人沮丧的限制是模板可以用不相关的类型进行特殊化的副作用,这是一种非常强大的工具,但会导致这种混乱。一般的经验法则是,不要将const/vvolatile限定或任何类型的引用放入模板参数中,除非这是模板类(如std::remove_reference
)的唯一原因。
然而,我刚刚意识到,你想要的是foo<int>
和foo<const int>
是相同的类型(ish),并且可以完成(有点)!
struct base {
virtual ~base(){}; //always have virtual destructor with polymorphism
virtual void dummy()=0; //pure virtual, forces override
};
template<typename T>
struct foo : public bar {
virtual void dummy() {}
};
template<typename T> struct foo<const T> : public foo<T> {};
template<typename T> struct foo<volatile T> : public foo<T> {};
template<typename T> struct foo<const volatile T> : public foo<T> {};
base* t1 = new derived<const int>;
derived<int>* t3 = dynamic_cast<derived<int>*>(t1); //hooray!
//you can go from derived<const int> to derived<int> but not the other way around
使用std::is_convertible<From*, To*>::value
#include<type_traits>
int main(){
using namespace std;
cout << std::is_convertible<int const, int>::value << endl; // print true
cout << std::is_convertible<int const*, int*>::value << endl; // print false
cout << std::is_convertible<int const, int>::value << endl; // print true
cout << std::is_convertible<std::string, int>::value << endl; // print false
cout << std::is_convertible<std::string*, int*>::value << endl; // print false
}
请注意,例如,您必须使用指针类型来获得关于const
ness的异常行为。
(我想在C++98中,boost::is_convertible
也可以这样做。)
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- 扩展类中的可选 vir 函数,测试它在运行时是否存在
- 是否可以在运行时强制转换模板参数?
- 在 c++ 中将集合转换为向量和向量转换为字符串时出现运行时异常
- 在 Linux 上没有 /proc/self/exe 的 C/C++ 运行时可执行文件的大小?
- Antlr cpp 运行时 任何错误的指针转换?
- 如何在运行时将指向派生类的 void* 正确转换为指向基类的 void*
- 积分转换的运行时检查
- 与shared_ptr相比,更小的运行时数据结构和更快的代码可实现独特的_ptr
- 使用向量将给定表达式转换为波兰表示法时出现运行时错误
- C++ 可执行文件在运行时找不到库,即使它在 /usr/lib 中(在 Linux 上)
- 动态强制转换的运行时检查
- 尝试运行可执行文件时出现分段错误
- 在 Qt 中将 x 可执行文件作为按钮事件运行时出错
- 运行时 kinect 输出的 3D 可视化
- 运行可执行文件时找不到共享库,即使共享库存在于指定的路径中
- Bash 代码,仅在当前可执行文件完成运行时在循环中运行可执行文件
- cl 生成的可执行文件在第一次运行时运行速度非常慢
- 薄板样条形状转换运行时错误 [使用代码 -1073741819 退出]
- 在c++中检查运行时的可转换性