lundi 1 mars 2021

Error due to rvalue to lvalue conversion and not using forward

The following code shows a segmentation fault both in windows & Linux machines. The Parent class stores a pointer, but due to rvalue to lvalue conversion, the Parent ends up storing a reference to a pointer. (This is as per my understanding, please correct it otherwise)

#include <iostream>
#include <vector>

class Root {
public:
    virtual void Print() = 0;
};

template<typename PointerType>
class Parent : public Root {
public:
    Parent(PointerType&& p): ptr(p) {}

    void Print() override {
        std::cout <<"About to deref ptr" << std::endl;
        std::cout << *ptr << std::endl;
    }

    PointerType ptr;
};

class Child {
public:
    Root * root;
    template<typename PointerType>
    Child(PointerType&& p) {
        root = new Parent<PointerType>(std::forward<PointerType>(p));
    }
};



std::vector<Child> v;

template<typename PointerType>
void MyFunction(PointerType&& ptr) {  

    Child ch(ptr); /// ptr is lvalue here

    /// FIX : Child ch(std::forward<PointerType>(ptr));

    v.push_back(std::move(ch));
}

int* getInt() {
    return new int(10);
}

int main() {
    MyFunction(getInt()); /// pass any rvalue pointer /// it could be "this" pointer also
    v[0].root->Print();
}

I convinced myself that, I always need to use std::forward as in when universal references are used (Inside the function MyFunction).

I am finding it difficult to understand the following

Why does reference to ptr becomes invalid inside the parent class? Is it because ptr becomes a local variable once it is used inside MyFunction and Child constructor gets a reference to this local only?

Thanks!

Aucun commentaire:

Enregistrer un commentaire