1

I'm using std::shared_ptr<T> for a lot of different types. Since I want to store all these different shared_ptrs in one vector, I thought having a std::vector<std::shared_ptr<void> >and cast to and from void if necessary.

I'm familiar with the following "bare pointer" usage

#include <iostream>

void print(void* void_ptr)
{
    int* int_ptr = static_cast<int*>(void_ptr);
    std::cerr << *int_ptr << std::endl;
}

int main()
{
    int* int_ptr = new int(4);
    void* void_ptr = static_cast<void*>(int_ptr);
    print(void_ptr);
    delete int_ptr;
}

This works flawlessly with g++ and afaik it's the proper way to do this if you have bare pointers. But now I want to have the same with std::shared_ptrs.

#include <iostream>
#include <memory>

void print(std::shared_ptr<void> void_ptr)
{
    std::shared_ptr<int> int_ptr = ??(void_ptr); // simple cast won't work
    std::cerr << *int_ptr << std::endl;
}

int main()
{
    std::shared_ptr<int> int_ptr = std::make_shared<int>(4);
    std::shared_ptr<void> void_ptr = ??(int_ptr); // same problem here
    print(void_ptr);
}

Is this even possible? There are a lot of different types which I have shared_ptrs to, but these types have little in common. They don't share a base class or something like that (if that's the only way, I'll do that, but it would be definitively more awesome with some sort of shared_ptr<void>).

stefan
  • 10,215
  • 4
  • 49
  • 90
  • 1
    You might want to read the following question/answers: http://stackoverflow.com/questions/5913396/why-do-stdshared-ptrvoid-work . I'm more or less a newbie on that particular question, so I have no knowledge to share, but the info on that link chould help reach a viable solution for you. – paercebal Sep 15 '12 at 20:50
  • If they don't have anything in common... why do you want to pass `void*`'s to them around? In general, if you're using `void*`, something has either gone terribly wrong, or you're trying to get a type out of a function's signature (ie: a function that can theoretically take any type, so that it can pass it to a function that takes a specific type). For the latter, you should be using `boost::any`, which is type-safe. – Nicol Bolas Sep 15 '12 at 20:51
  • @NicolBolas: Basically I want to separate the "math" from "the code". I have classes that represent a mathematical structure. Of each such class there has to be an object in one class `Foo`. Now I want to have a layer which let's a `foo` object access math objects without knowing all of them. I take care of correct use and I consider void* as a "I have a pointer to something I want to pass around without all knowing what it really is.". I don't want to use `boost`. – stefan Sep 15 '12 at 20:58
  • @stefan: "*Now I want to have a layer which let's a foo object access math objects without knowing all of them.*" Which is exactly what *inheritance* is for. Now it's possible you may be doing something where inheritance doesn't work (calling different functions for two parameters and so forth), but unless that's the case, I don't see the problem. – Nicol Bolas Sep 15 '12 at 21:01
  • @NicolBolas I'm not using custom classes alone but also a mixed range of integers, std::strings and stuff. A base class would just be messy, so I hoped for a imo nicer way. – stefan Sep 15 '12 at 21:05
  • Perhaps a template like `template void deleter(void * p) { delete static_cast(p); }` could be used to make shared pointers, like `std::shared_ptr(new Foo, deleter);`. – Kerrek SB Sep 15 '12 at 23:41

1 Answers1

1

std::static_pointer_cast performs this function. However, this is generally an extremely bad idea- why not boost::any or boost::variant or something? This weakly typed and weakly enforced code will only bite you in the arse.

Puppy
  • 144,682
  • 38
  • 256
  • 465