2

How to pass std::vector<void*> * as std::vector<MyStruct*>* to a function?

The function declaration is void SetDataReferences(std::vector<MyStruct*>* pVector);

if I pass std::vector<void*> * as std::vector<MyStruct*>* I am getting below error

error C2664: 'CTagFilterComboBox::SetDataReferences' : cannot convert parameter 2 from 'std::vector<_Ty> *' to 'std::vector<_Ty> *'

How to resolve this?

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
user369287
  • 692
  • 8
  • 28
  • a `std::vector` is a type completely unrelated to a `std::vector` (apart from being an instantiation of the same template, which wont help you much). You need to supply a conversion – 463035818_is_not_an_ai Sep 21 '18 at 14:31
  • 3
    Does your source type have to be a `std::vector *`? Normally `void*` isn't needed in C++ – NathanOliver Sep 21 '18 at 14:31
  • Copy elements of the `std::vector` to the `std::vector`. Then pass the address of the `std::vector`. Be aware that, if any of the `void *`s don't point at a `MyStruct`, the function will have undefined behaviour if it dereferences those pointers. – Peter Sep 21 '18 at 14:32
  • If you're temped to do `(std::vector*)`, I'm afraid it will work. But, it's [UB](https://stackoverflow.com/a/4105123/1505939). – Scheff's Cat Sep 21 '18 at 14:36

3 Answers3

4

Unfortunately std::vector<void*> is a completely different type to std::vector<MyStruct*>*, so no cast is going to work.

You need to rebuild the vector from scratch, and pass a pointer to that to your function, and hope that the static_cast on each element is valid.

One way, given a std::vector<void*>* foo;

std::vector<MyStruct*> temp;
for (void* p : *foo){
    temp.push_back(static_cast<MyStruct*>(p));
}
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

If you don't need to modify the vector<void*> foo then you could just work with the underlying data, by changing your function signature to: void SetDataReferences(MyStruct*const* pVector, const size_t length) (remember that const is left associative, so this is a pointer-to-constant-pointers-to-MyStructs.) This can be called as follows:

SetDataReferences(reinterpret_cast<MyStruct*const*>(data(foo)), size(foo))

If you needed to modify the elements of vector<void*> foo (not the size) you still have the recourse of changing your function signature to: void SetDataReferences(MyStruct** pVector, const size_t length) This can be called as follows:

SetDataReferences(reinterpret_cast<int**>(data(foo)), size(foo))

Live Examples

If you need to modify vector<void*> foo that gets more complicated, you'll need to accept the vector<void*> as your function signature does in the question and cast the elements on use rather than as a group.

Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 1
    @Scheff [`data`](https://en.cppreference.com/w/cpp/iterator/data) is now preferred because it can be used interchangeably on arrays and containers. – Jonathan Mee Sep 21 '18 at 14:42
  • 1
    Yepp. Got it: [`std::data()`](https://en.cppreference.com/w/cpp/iterator/data), [`std::size()`](https://en.cppreference.com/w/cpp/iterator/size). – Scheff's Cat Sep 21 '18 at 14:42
0

I got solution for my problem from this link https://www.codeproject.com/Questions/1261243/How-to-pass-std-vector-void-as-std-vector-mystruct and it is working for me.

If I call SetDataReferences((std::vector<MyStruct*>*)(&p1)) it is working for me without getting any compiler error.

user369287
  • 692
  • 8
  • 28