C++11 Dynamic Cast If Else Chain -> 开关

标签 c++ templates c++11 rtti

考虑以下几点:

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;
};

这里只有三种可能的 T 类型——int、string、char——但是如果可能的类型列表更长,比如 n,则 if else 链的执行时间为 O(n)。

处理这个问题的一种方法是以某种方式在 D 中存储一个额外的类型代码,然后在类型代码上切换

RTTI系统肯定已经有这样的代码了。有什么办法可以访问它并打开它吗?

或者是否有更好的方法来完成我想做的事情?

最佳答案

C++11 几乎就在那里。

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

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

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

关于C++11 Dynamic Cast If Else Chain -> 开关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14016810/

相关文章:

c++ - boost mpi 请求的 m_handler 的目的是什么

C++ 项目作为静态库编译,作为动态库失败(链接器错误)。为什么?

c++ - 访问模板父类的静态成员

C++20 概念要求运算符重载结合用户定义模板运算符重载函数

c++ - 成员指针的大小和 reinterpret_cast 是否固定?

c++ - Qt 可以缩短一条线,使其不退出到达终点吗?

c++ - 从变换范围构造新容器

c++11 - CUDA 8.0 : Compile Error with Template Friend in Namespace

c++ - “throw expression code”返回d> 1e7是什么?抛出std::overflow_error(“too big”):d;意思?

c++ - 值初始化是否适用于原子对象?