迭代时在 std::vector 中保存指向不同类型的指针

Posted

技术标签:

【中文标题】迭代时在 std::vector 中保存指向不同类型的指针【英文标题】:Save pointer to differents type in a std::vector while iterating 【发布时间】:2018-08-02 15:48:29 【问题描述】:

考虑以下函数 (myfct)。当此函数返回时,数据指向 uint16_t、float_t 或 double_t。

在 main() 中,这个函数在 for 循环中被调用。我希望每次迭代都使用它指向的类型将“数据”保存在 std::vector 中。我怎样才能做到这一点?提前致谢。

PS:容器不一定是向量,可以是其他任何东西,我只是想保存“数据”而不丢失指针类型信息。

void myfct(void*&data, int id) 
if(id==1) 
  uint16_t* ptr = ...;  
  data = ptr;

else if(id==2) 
  float_t* ptr = ...;  
  data = ptr;

else if(id==3) 
  double_t* ptr = ...;  
  data = ptr;



int main() 

    void* dataPtr = nullptr;
    vector<?> myVec; //how should I template my vector? which typename?
    for(int i = 0, i<5, i++) 
    
        myfct(dataPtr , i);  //note that dataPtr is passed by reference
        myVec.push_back(dataPtr ); //here dataPtr point to either uint16_t, 
        //float_t or double_t. I want to save it with the type it point to.
    

【问题讨论】:

你想要的是std::variantstd::any 每当您在 C++ 中使用 void * 时,您很可能做错了。 一个std::vector只能保存一个类型的数据。 @Gaetan “每个容器一个类型”位适用于所有标准容器,而不仅仅是vector。如果您想要多种类型,请使用多个容器(或 variantany 的容器,如 Nathan 建议的那样)。 我想用它指向的类型保存它。您可能需要 3 个向量,每个类型一个。 【参考方案1】:

如果您无权访问std::variant,方法如下:

class custom_type 
    int id;
    union data_holder
    
        uint16_t i;
        float_t f;
        double_t d;
     data;

现在,您可以拥有vector&lt;custom_type&gt;,如果您想使用数据点,您可以这样做

custom_type c = myvec.back();
if( c.id == 1 ) 
    uint16_t val = c.data.i;
    // Process val in a uint way
 else if( c.id == 2 ) 
    float_t val = c.data.f;
    // Process val in a float way
 ...

您可以了解更多关于联合的信息here。现在,为了使您的代码轻松处理数据类型(因此您不必一遍又一遍地编写类似的“以 X 方式处理 val”),您可以使用 templates。例如,

template <typename T>
T calculate(T val) 
    // Do stuff with val
    return computed_val;

现在,

custom_type c = myvec.back();
if( c.id == 1 ) 
    uint16_t val = calculate<uint16_t>(c.data.i);
    cout << val;
 else if( c.id == 2 ) 
    float_t val = calculate<float_t>(c.data.f);
    cout << val;
 ...

【讨论】:

std::variant 无论如何只是一个联合的包装器。如果您 需要 它是问题中所示的指针,那么您可以让联合封装指针而不是类型本身。不过,我认为这不是正确的做法,您应该只使用指向 custom_type 的指针。【参考方案2】:

你想要的是多态,例如,一个基类(可以是一个接口/abc)然后是派生类,它们实现了一些typeof函子。如果你愿意,我可以举个例子,但我认为你自己学习如何做会更有价值。 另一种方法是使用boost::variantboost::any

【讨论】:

以上是关于迭代时在 std::vector 中保存指向不同类型的指针的主要内容,如果未能解决你的问题,请参考以下文章

std::vector begin(),end()是内联函数么

如何在不丢失现有数据的情况下调整 std::vector 的大小?

从 Go 中迭代`std::vector<std::string>`?

智能指针的迭代和容器

为啥 std::set::find 不提供提示迭代器?

std::vector 的不完整类型