以下是尝试使用修改后的语义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
)抱怨无效的强制转换。为什么它不起作用,我应该怎么做而不是这个演员?
答案 0 :(得分:3)
您会看到此编译器错误消息,因为reinterpret_cast
无法通过私有继承进行强制转换。请检查以下主题:difference between c++ casts,conversion which may be handled by 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在这种情况下是安全的。
答案 1 :(得分:0)
我建议你的deref_shared_ptr
实现一个接收std::shared_ptr
参数的构造函数,这样就可以进行转换。现在,您的编译器不知道如何从deref_shared_ptr
创建std::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
构造使您的类型兼容。