有没有办法将类型说明符存储在变量中?我已经四处搜索并找到了TypeID和声明,但是它们都没有根据我想要的。声明类型不会生成变量,typeID通常用于typeID((。名称((。
由于typeId((。名称((输出类型为const char*,可以存储和传递,是否有一个函数可以将const char*转换回类型指定符?喜欢:
int a = 1;
auto t = typeid(a).name();
some_function(t) b = 1; //gives int b
我知道decltype确实可以做到这一点,但是它不能"存储"类型的说明符。
在我最近的项目中,我遇到了一个奇怪的情况,即函数参数的类型在每个呼叫上可能会有所不同。通常,使用功能模板会这样做,但是它要么需要将所有代码放入本项目中不允许的标题中,要么使用明确的插入,因为很难列出所有类型,因此可能会变得凌乱。另外,编写各种类型的多个功能过载也很混乱。
如果有一种方法可以将类型说明符存储为变量,那么我可以使用void*传递输入的地址,然后将包含类型说明符的变量传递到该函数中,然后将void*送回其原始类型?
以某种方式,typeid((。名称((已经提供了一种存储和传递变量类型的方法,我想知道是否有一种优雅的方式可以将其转换回类型的指定词,而无需编写" 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
}
我知道功能模板对此有好处,但不能如上所述使用它。因此,我希望将" fory stype"更改为一个void*,以指向地址,并从typeid((。名称((生成的const char*标记实际类型。但是我找不到将const char*转换回类型指定符的好方法。
有三个选项
- 超载集,
- 功能模板或
- 类型擦除
但是在某个时候,您要么必须使用模板或编写一定数量的样板/过载/分支。
" [a]类型的函数参数[]可能会有所不同的最佳选择是一个函数模板,因为这基本上是模板的用例。
如果它们不能在项目的(可能(公共标题文件中,则可能会奏效某种内部标头。如果仅在特定点使用该代码,则可以在源文件中定义模板(牺牲可重复使用性(。
。 C 17中的std::any
是某种类型擦除的句法糖,如果您投射到any
不持有的类型。
void Base::Set(const int& id, std::any const& value)
{
switch(id)
{
case static_cast<int>(BASE_PARA::A):
this->a = std::any_cast<int>(value);
break;
// ... and so on ...
}
}