C++ 11 Dynamic Cast If Else Chain - > Switch

And*_*zos 6 c++ templates rtti c++11

考虑以下:

struct B { };

template<typename T>
struct D : B
{
    T t;
}

void g(int i) { ... }
void g(string s) { ... }
void g(char c) { ... }

void f(B* b)
{
    if (dynamic_cast<D<int>*>(b))
    {
        g(dynamic_cast<D<int>*>(b)->t);
    }
    else if (dynamic_cast<D<string>*>(b))
    {
        g(dynamic_cast<D<string>*>(b)->t);
    }
    else if (dynamic_cast<D<char>*>(b))
    {
        g(dynamic_cast<D<char>*>(c)->t)
    }
    else
        throw error;
};
Run Code Online (Sandbox Code Playgroud)

这里只有三种可能类型的T - int,string,char - 但如果可能类型的列表更长,比如说n,则if else链将执行O(n).

解决这个问题的一种方法是在D中以某种方式存储额外的类型代码,然后switch在类型代码上存储.

RTTI系统必须已经有这样的代码.有没有办法访问它并打开它?

或者有更好的方法来做我想做的事情吗?

Pot*_*ter 4

C++11 已经快到了。

在 C++03 中这是不可能的,因为获取编译时常量(case需要)的唯一方法是通过类型系统。由于typeid始终返回相同的类型,因此它无法为switch.

C++11 添加了constexprandtype_info::hash_code作为类型的唯一标识符,但没有将它们组合起来。您可以typeid在类型名称或静态类型表达式的常量表达式中使用,但由于hash_code是非constexpr函数,因此您无法调用它。

当然,有多种解决方法,您描述了其中一种,其中最常见的是使用模板元编程将访问者应用于类型向量。