是否可以在变量中存储类型说明符?我到处搜索并找到typeid和decltype,但是它们都不如我所愿。 decltype不会生成变量,而typeid通常用于typeid()。name()。
由于typeid()。name()将类型说明符输出为const char *,可以将其存储和传递,是否有将const char *转换回类型说明符的函数?喜欢:
int a = 1;
auto t = typeid(a).name();
some_function(t) b = 1; //gives int b
我知道decltype确实可以做到这一点,但是它不能“存储”类型说明符。
在我最近的项目中,我遇到了一个奇怪的案例,其中每次调用时函数参数的类型可能会有所不同。通常,使用函数模板是可以的,但是它要么需要将所有代码放在该项目中不允许的标头中,要么使用显式实例化,因为很难列出所有类型,因此可能会造成混乱。另外,为每种类型编写多个函数重载也很麻烦。
如果有一种方法可以将类型说明符存储为变量,那么我可以使用void *传递输入的地址,并将包含类型说明符的变量传递给函数,然后将void *转换回其原始类型?
以某种方式,typeid()。names()已经提供了一种存储和传递变量类型的方法,我想知道是否存在一种优雅的方法可以将其转换回类型说明符,而无需编写长长的“ strcmp”或其他列表手动转换。
谢谢!
编辑: 关于我的项目的更多信息,该函数用作私有类成员的设置器,第一个输入是有关成员ID的枚举,第二个是值。该类也可以被继承。该项目要求在标头中放置尽可能少的代码。此项目使用OpenCV。
在Header.h中:
#include "some_other_custom_class.h"
#include <string>
enum BASE_PARA
{
A,
B,
C
}
class Base
{
public:
Base() = default;
virtual ~Base() = default;
//<sometype> may vary regarding the member
virtual void Set(const int& id, const <sometype>& value);
private:
int a;
float b;
map<std::string, double> c;
}
enum DERIVED_A_PARA
{
D,
E
}
class DerivedA : public Base
{
public:
//inherit Set()
virtual void Set(const int& id, const <sometype>& value) override;
private:
map<int, <some_custom_class>> d;
vector<double> e;
}
class DerivedB : public DerivedA //and so on
{
}
在Cpp.cpp中:
void Base::Set(const int& id, const <sometype>& value)
{
//processing the input regarding the private member
//<do something here>
switch(id)
{
default:
break;
case A:
a = value;//which means in here <sometype> should be int
break;
case B:
b = value;//<sometype> should be float
break;
case C:
//<sometype> should be map<string, double>
if (<some_code_to_ensure_value_is_not_empty>)
return;
c["first"] = value["first"];
c["second"] = value["first"] + value["second"];
break;
}
}
void DerivedA::Set(const int& id, const <sometype>& value)
{
//something like above
}
我知道函数模板对此很有用,但是不能如上所述使用它。因此,我希望将“ sometype”更改为void *以指向地址,并从typeid()。name()生成的const char *标记为实际类型。但是我找不到将const char *转换回类型说明符的好方法。
答案 0 :(得分:2)
共有三个选项
但是在某些时候,您要么必须使用模板,要么编写一定数量的样板文件/重载/分支。
“ [a]类型的函数参数[可能]变化”的最佳选择是函数模板,因为这基本上是模板的用例。
如果它们不能位于项目的(可能是)公共头文件中,则可能会产生某种内部头文件。如果仅在特定位置使用代码,则可以在源文件内定义模板(以提高可重用性)。
std::any
是一种用于类型擦除的语法糖,如果您强制转换为{所不支持的类型,则它可以通过std :: bad_any_cast异常为您提供更优雅的类型擦除{1}}。
any