0

I have problem with shared_ptr and 'this' pointer. I found sollution to use enable_shared_from_this but:

std::shared_ptr<Binary_search_tree> x = shared_from_this();

throws exception. How to use it properly in my case?

here is code with context:

#pragma once
#include <memory>
#include <string>

bool def_comparator(int x, int y) {
    if (x>y)
    {
        return true;
    }
    else {
        return false;
    }
};

template <typename T>
class Binary_search_tree : public std::enable_shared_from_this<Binary_search_tree<T>>
{
public:
    std::shared_ptr<Binary_search_tree> up;
    std::shared_ptr<Binary_search_tree> left;
    std::shared_ptr<Binary_search_tree> right;
    int key;
    T data;
bool(*comparator)(int, int);

Binary_search_tree(T x, const int key, bool(*comparator)(int, int))
{
    if (comparator==NULL)
    {
        this->comparator = &def_comparator;
    }
    else {
        this->comparator = comparator;
    }
    this->data = x;
    this->key = key;
}
Binary_search_tree()
{
}
~Binary_search_tree()
{
}

bool insert(T data, const int key)
{
    std::shared_ptr<Binary_search_tree> y;

    std::shared_ptr<Binary_search_tree> x = shared_from_this();
    if (comparator(key, x->key))
    {
        x = x->left;
    }
    else {
        x = x->right;
    }
    while (x != NULL)
    {
        y = x;
        if (comparator(key,x->key))
        {
            x = x->left;
        }
        else {
            x = x->right;
        }
    }
    Binary_search_tree<T> *tmp = new Binary_search_tree<T>(data, key, this->comparator);
    tmp->up = y;
    if (tmp->key == y->key)
    {
        return false;
    }
    if (comparator(tmp->key,y->key))
    {
        y->left = shared_ptr<Binary_search_tree<T>>(tmp);
    }
    else {
        y->right = shared_ptr<Binary_search_tree<T>>(tmp);
    }
    return true;
    }
}

EDIT: I added whole insert method code @Tyker I don't try to access members that way, I need to go throught my tree to add new element using x and ypointer. If there is no 'next element' the pointer stays as is and then new element is added. @G.M. do you mean sth like this:

std::shared_ptr<Binary_search_tree<T>> x(new Binary_search_tree<T>); 
x = shared_from_this();
Orzel94
  • 93
  • 1
  • 1
  • 8
  • you don't need to use shared_from_this() to access class members you can access them normally – Tyker Dec 01 '18 at 22:39
  • The `std::enable_shared_from_this` is considered by some people (e.g., Sean Parent) to be a bad pattern, because the object is self-aware that it is (and really then ought to only be) held in a shared_ptr. Their position is that in general objects should be ignorant of how they're owned and life-cycle managed. – Eljay Dec 01 '18 at 22:44
  • How are you using the code shown? Invoking `shared_from_this()` is only permissible if a valid `std::shared_ptr` to the object in question already exists [ref](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this). – G.M. Dec 01 '18 at 22:59
  • I've edited question and added whole problematic method body. – Orzel94 Dec 02 '18 at 12:26
  • You can only use `shared_from_this` in a member function of a class, never in a standalone function. – zett42 Dec 02 '18 at 12:30
  • @Eljay I undestand your point but in that case I would need to convert usual Binary_search_tree shared_ptr<...> . Even then I'll still want to know how to deal with shared_ptr in such case. – Orzel94 Dec 02 '18 at 12:30
  • @zett42 this is a member function (and yes it is in .h file) – Orzel94 Dec 02 '18 at 12:32
  • This is hard to see from the code sample... – zett42 Dec 02 '18 at 12:34
  • Also, header guards are better than `#pragma once`. q.v. https://stackoverflow.com/questions/1143936/pragma-once-vs-include-guards/33142610#34884735 – Eljay Dec 02 '18 at 13:53
  • The code is doing a `new`, but (via `std::enable_shared_from_this`) had claimed that it was going to be `std::make_shared`. Although not illegal, it is highly suspect, and one has to be very careful not to conflate objects created the `new` way with objects created the `std::make_shared` way. – Eljay Dec 02 '18 at 14:04
  • @Eljay I understand (i hope so) but I don't know how to fix it. I have finally refactored insert method so x/y are now casual pointers (and create shared_ptr only for left/right/up purpose) and it works fine but my point is to understand how they work deeply and what is the difference between this: [link](https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this) and std::make_shared and how it use properly (maybe templates are specific i don't know). I'm moving from C# back to c++ and even Stephen Prata in his 1.2k pages book is laconic about it; – Orzel94 Dec 02 '18 at 17:48

0 Answers0