【问题标题】:Array of templated structs模板化结构数组
【发布时间】:2012-10-07 23:59:03
【问题描述】:

我有从 Base 结构派生的 int 模板化的结构。

struct Base { int i; double d; }; 
template< int N > struct Derv : base { static const int mN = N; };

我需要创建一个 Derv 数组,其中 N 可以针对该数组中的每个结构而变化。我知道 C/C++ 不允许使用不同类型的对象数组,但有没有办法解决这个问题?我正在考虑以某种方式分离类型信息(诸如指向 Base struct 的指针或 union 的使用之类的提示在我脑海中浮现,但是所有这些我不知道如何存储每个数组元素的类型信息以供在编译期间使用)。可以看到,每个 Derv 的内存模式都是一样的。

我需要稍后在我的代码中访问每个数组元素的类型以进行模板特化。这一切的总体目标是拥有一个编译时调度机制,而无需在代码中的某处进行运行时“类型切换”。

【问题讨论】:

  • 目前我看不出让Derv 成为模板类有什么用处。一个都没有。所以首先你应该想知道你问的问题是否正确。
  • 制作Base的向量,完成。
  • 重点是静态调度的参数(我不想包含整个代码,但通常有模板化的函数根据 Derv 的类型表现不同)。所有这些都发生在对性能至关重要的代码中,所以我宁愿避免使用虚函数、函数指针和类似的东西。
  • @Kerrek SB:是的,但是如何保留每个元素的类型信息?
  • @JakubMertlik:通过size() 成员函数。

标签: c++ templates struct


【解决方案1】:

这绝对是不可能的。如果你这样做了

int i;
std::cin >> i;
some_magic_array X[size];

那么X[i]的类型是什么?哦,等等,你不可能知道。这与 C++ 无关,根本不可能。这就是为什么永远不会存在允许这样做的some_magic_array

除非您有效地使用 std::tuple 并保证 i 是 constexpr。那么你绝对可以用std::get&lt;i&gt;(tup); 做到这一点。

【讨论】:

  • 好的,我将分析它和 Alexandrescu 的类型列表,看看是否有帮助。谢谢大家。
【解决方案2】:

我猜你可以使用 ptr = dynamic_cast&lt;Type&gt;(element); .. ptr 将等于 NULL 如果它是错误的类型。 例如:

#include <map>
#include <cmath>
#include <vector>
#include <string>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <iostream>


using namespace std;

struct Base { int i; double d; Base(){}; virtual ~Base(){};}; 
template< int N > struct Derv : public Base { static const int mN = N; ~Derv(){}; };

int main(int argc, char **argv){
    Base* arr[2];
    arr[0] = new Derv<10>;
    arr[1] = new Derv<5>;
    Derv<10> *ptr = dynamic_cast<Derv<10>* >(arr[0]);
    Derv<5> *ptr2 = dynamic_cast<Derv<5>* >(arr[0]);
    cout << ptr << endl << ptr2 << endl;
    return 0;
}
// That should print 
0x9571008 //ptr to object will differ every time.
0 // Null because of wrong type.

但您需要在结构中定义虚拟析构函数才能使其工作,和/或虚拟函数。

【讨论】:

  • 不是 dynamic_cast 仅适用于带有虚拟的结构吗?另外,我需要在运行时检查返回值,这相当于类型切换(我想避免)。
  • 是的,需要 virtuals .. 啊哈 .. 那么,您有什么想法避免类型切换,因为您不知道数组元素的类型?!
  • 通过模板特化的静态分派(在上面的 cmets 之一中描述)。
  • 您可以制作模板函数,并让编译器进行链接。 :D 如void operate(Derv&lt;10&gt; obj) {} ...等
  • 可以,但是如何制作Derv的数组呢? (这是最初的问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多