0

以下是实现具有修改语义的共享指针的尝试operator==

template <typename T>
struct deref_shared_ptr: private std::shared_ptr<T> {
    using Base = std::shared_ptr<T>;
    // ... using statements to include functionality from the base.

    bool operator==(const deref_shared_ptr rhs) const {
        return (**this == *rhs);
    }
};

我正在努力实现std::make_shared这种类型的等价物。这是我的尝试:

template< class T, class... Args >
deref_shared_ptr<T> make_deref_shared( Args&&... args ) {
    return reinterpret_cast<deref_shared_ptr<T>>(std::make_shared<T>(args...));
}

这不起作用:编译器 ( g++ 5.4.0) 抱怨无效转换。为什么它不起作用,我应该怎么做而不是这个演员?

4

2 回答 2

2

您会看到此编译器错误消息,因为reinterpret_cast无法通过私有继承进行强制转换。请检查有关此主题的以下主题:c++ casts 之间的区别, c -style cast only 可以处理的转换

通过private继承的唯一方法是 c 风格的演员表。因此,如下更改您的示例会使您的示例工作:

template< class T, class... Args >
deref_shared_ptr<T> make_deref_shared(Args&&... args) {
    return (deref_shared_ptr<T>)(std::make_shared<T>(args...));
}

在一般情况下,c 样式转换是不安全的,因为它在多重继承和其他一些情况下可能无法正常工作,但 AFAIK 在这种情况下是安全的。

于 2016-07-31T08:21:03.180 回答
1

我建议您deref_shared_ptr实现一个接收std::shared_ptr作为参数的构造函数,以便可以进行转换。现在你的编译器不知道如何deref_shared_ptrstd::shared_ptr. 这正是我们将教你的编译器做的事情。

我注意到您添加了一个自定义operator==来正确比较您的类型与std::shared_ptr. 在这里,我们想做同样的事情,但使用构造函数。我们需要一个构造函数,它可以使用您的类型正确构造一个std::shared_ptr!

构造函数如下所示:

template<typename T>
struct deref_shared_ptr : private std::shared_ptr<T> {
    // An alias to the parent may help msvc with templated parent types
    using parent = std::shared_ptr<T>; 

    // Implement a constructor that takes shared_ptr by copy and move
    deref_shared_ptr(const parent& ptr) : parent{ptr} {}
    deref_shared_ptr(parent&& ptr) : parent{std::move(ptr)} {}

    // stuff...
};

然后,make 函数的实现变得微不足道:

template<typename T, typename... Args>
deref_shared_ptr<T> make_deref_shared(Args&&... args) {
    // Don't forget perfect forwarding here!
    return std::make_shared<T>(std::forward<Args>(args)...);
}

编辑:

或者,如果你的构造函数没有做任何操作,你可以使用继承构造函数:

template<typename T>
struct deref_shared_ptr : private std::shared_ptr<T> {
    using parent = std::shared_ptr<T>; 

    // Implement constructors
    using parent::parent;

    // stuff...
};

这将简化构造函数的实现,并使您的类型通过构造与std::shared_ptr.

于 2016-07-31T16:09:04.797 回答