Невозможно преобразовать из std :: shared_ptr <_Ty> в std :: shared_ptr <_Ty> - PullRequest
0 голосов
/ 25 ноября 2018

Я получаю следующую ошибку:

ошибка C2440: «static_cast»: невозможно преобразовать из «std :: shared_ptr <_Ty>» в «std :: shared_ptr <_Ty> стек \ genericstack.h 36 1 стек

GenericStack.h

#ifndef _GENERIC_STACK_TROFIMOV_H_
#define _GENERIC_STACK_TROFIMOV_H_

#include <memory>

class GenericStack {
    struct StackNode {
        std::shared_ptr<void> _data; 
        StackNode* _next;
        StackNode(const std::shared_ptr<void>& data, StackNode* next) 
            : _data(data), _next(next) {

        }
    };

    StackNode* _top; 

    GenericStack(const GenericStack&);
    GenericStack& operator=(const GenericStack&);

protected:
    GenericStack();
    ~GenericStack();
    void push(const std::shared_ptr<void>&);
    void pop();
    std::shared_ptr<void>& top();
    bool isEmpty() const;
};

template <class T>
class TStack: private GenericStack {                  
public:
    void push(const std::shared_ptr<T>& p) { GenericStack::push(p); }
    void pop() { GenericStack::pop(); }
    std::shared_ptr<T> top() { return static_cast<std::shared_ptr<T>>(GenericStack::top()); }
    bool empty() const { return GenericStack::isEmpty(); }
};

#endif

GenerickStack.cpp

#include "GenericStack.h"

GenericStack::GenericStack()
    :_top(0) {

};
GenericStack::~GenericStack() {
    while(!isEmpty()) {
        pop();
    }
};

void GenericStack::push(const std::shared_ptr<void>& element) {
    _top = new StackNode(element, _top);
}

std::shared_ptr<void>& GenericStack::top() {
    return _top->_data;
}
void GenericStack::pop() {
    StackNode* t = _top->_next;
    delete _top;
    _top = t;
}

bool GenericStack::isEmpty() const {
    return !_top;
}

Main.cpp

#include <iostream>
#include "GenericStack.h"

int main() {
    TStack<int> gs;

    std::shared_ptr<int> sh(new int(7));
    gs.push(sh);
    std::cout << *gs.top() << std::endl;

    return 0;
}

Почему я получаю ошибку?

Я ожидаю, что приведение произойдет успешно, поскольку с необработанными указателями я всегда могу получить из void* на указатель реального типа.

Здесь я хочу создать шаблон стека.Но я пытаюсь использовать как можно больше кода, чтобы шаблонные классы не набухали слишком сильно.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Вы получаете эту ошибку, потому что static_cast требует, чтобы типы from и to были конвертируемыми.Для shared_ptr это будет сохраняться, только если перегрузка c'or 9 будет участвовать в разрешении перегрузки.Но это не так, поскольку void* неявно не преобразуется в другие типы указателей объектов в C ++, для него требуется явное static_cast.

Если вы хотите преобразовать общие указатели на основе static_casting управляемоготипы указателей, вам нужно использовать std::static_pointer_cast, вот для чего он нужен.

Так что после подключения исправьте

 std::shared_ptr<T> top() { return std::static_pointer_cast<T>(GenericStack::top()); }

Ваша оболочка тонкого шаблона будет работать нормально.

0 голосов
/ 25 ноября 2018

Взгляните на список конструкторов для shared_ptr.Вы пытаетесь использовать перегрузку 9, более конкретно, перегрузку шаблона с Y = void и T = int.Однако эта перегрузка шаблона не участвует в разрешении перегрузки , поскольку void* не является неявно конвертируемым в int*.Другими словами, вы не можете конвертировать, даже явно, shared_ptr<void> в shared_ptr<T>, если вы не можете неявно конвертировать void* в T*.

Почему бы не использовать шаблон в первую очередь (переместить GenericStack функциональность TStack), вместо того, чтобы пытаться справиться с void*?

Но я пытаюсь повторно использовать столько кода, сколько смогу, чтобы шаблонные классы не набухали слишком сильно.

Под "волной" я предполагаю, что вы имеете в виду, что шаблонное решение будет генерировать слишком много экземпляров?Есть ли у вас основания полагать, что их будет действительно слишком много?

...