1

I am trying to initialize a vector of shared pointers to base class with a number of shared pointers to derived class, using brace initialization. The code (after stripping out irrelevant details) looks like this:

#include <vector>
#include <memory>
#include <iostream>

struct Base {
    Base(double xx) { x = xx; }
    virtual ~Base() {}
    double x;
};

struct Derived : public Base {
    Derived(double xx) : Base(xx) {}
};

int main(void) {
    std::vector<std::shared_ptr<Base>> v = {
        std::make_shared<Derived>(0.1),
        std::make_shared<Derived>(0.2),
        std::make_shared<Derived>(0.3)
    };
    std::vector<std::shared_ptr<Base>> v4(3);
    v4[0] = std::make_shared<Derived>(0.1);
    v4[1] = std::make_shared<Derived>(0.2);
    v4[2] = std::make_shared<Derived>(0.3);

    std::cout << "Without brace initialization: " << std::endl;
    for (auto x : v4) {
        std::cout << x->x << std::endl;
    }

    std::cout << "With brace initialization: " << std::endl;
    for (auto x : v) {
        std::cout << x->x << std::endl;
    }
}

When I compile this code under Visual Studio 2013 and run it in the console, the result is:

Without brace initialization:
0.1
0.2
0.3
With brace initialization:
7.52016e-310

and then the program crashes. Is this to be expected and brace initialization is incompatible with implict conversion of std::shared_ptr<Derived> to std::shared_ptr<Base>, or is that a bug in the Visual Studio? Does brace initialization do some magic under the hood which blocks the shared pointer conversion (e.g. taking references to pointers)?

quant_dev
  • 6,181
  • 1
  • 34
  • 57
  • 1
    There is indeed a bug in VS2013 relating to list-init, shared_ptrs and double deletion. I'll try to find it.. (should have a dup on SO, too) – dyp Apr 20 '14 at 23:47
  • 1
    @Mgetz Not for shared_ptr. – dyp Apr 20 '14 at 23:47
  • @dyp source? it would seem to me you're still deleting a pointer to the base class in this case as the `shared_ptr` has been cast – Mgetz Apr 20 '14 at 23:48
  • @Mgetz A shared_ptr stores a "deleter" as part of the bookkeeping object. [Here's a detailed language-lawyer question](http://stackoverflow.com/questions/19846444/does-shared-ptrs-dtor-require-the-use-of-a-deleter) about this feature. – dyp Apr 20 '14 at 23:49
  • Duplicate? http://stackoverflow.com/q/20297191/420683 – dyp Apr 20 '14 at 23:51
  • @dyp I'd still put one to be safe, it's not that much code and it prevents idiots like me asking why it's not there. – Mgetz Apr 20 '14 at 23:51
  • @Mgetz It does need it, but this is irrelevant for this question, isn't it? – quant_dev Apr 20 '14 at 23:52
  • @Mgetz I agree. (I.e. it doesn't need one, but typically it helps more than it hurts). – dyp Apr 20 '14 at 23:52
  • I think it's pretty much a dup of this question: http://stackoverflow.com/q/22924358/420683 Note that there are more bugs than just this one in VS2013's implementation of list-initialization. – dyp Apr 20 '14 at 23:55
  • Also related: http://stackoverflow.com/q/19747981/420683 – dyp Apr 20 '14 at 23:56
  • I agree, it is a duplicate. I did look for answers before submitting my own... – quant_dev Apr 21 '14 at 00:00

0 Answers0