自定义智能指针和比较运算符的多项式数
假设我想实现一个智能指针 a_ptr
,它可以与其他智能指针进行比较。
然后我需要为其余的运算符实现比较运算符的所有排列:
template<class T, class U>
bool operator==(const a_ptr<T>& a, const a_ptr<U>& b)
{
return a.get() == b.get();
}
template<class T, class U>
bool operator==(const std::shared_ptr<T>& a, const a_ptr<U>& b)
{
return a.get() == b.get();
}
template<class T, class U>
bool operator==(const a_ptr<T>& a, const std::shared_ptr<U>& b)
{
return a.get() == b.get();
}
等等。
那么也许我想实现另一个智能指针 b_ptr
,这将为每个比较运算符提供 6 个版本(因为我希望它也可以与 a_ptr
一起使用),显然不是易于管理。
有什么办法可以解决这个问题吗?
编辑:
我应该提到我想围绕智能指针创建包装器,在这种情况下这个问题更有意义,例如
template<typename T>
class a_ptr
{
public:
const T* get() const {return p_.get();}
private:
std::shared_ptr<T> p_;
};
template<typename T>
class b_ptr
{
public:
const T* get() const {return p_.get();}
private:
a_ptr<T> p_;
};
Lets say I want to implement a smart pointer a_ptr
which can be compared with other smart pointers.
Then I need to implement all permutations of the comparison operators:
template<class T, class U>
bool operator==(const a_ptr<T>& a, const a_ptr<U>& b)
{
return a.get() == b.get();
}
template<class T, class U>
bool operator==(const std::shared_ptr<T>& a, const a_ptr<U>& b)
{
return a.get() == b.get();
}
template<class T, class U>
bool operator==(const a_ptr<T>& a, const std::shared_ptr<U>& b)
{
return a.get() == b.get();
}
and etc... for the rest of the operators.
Then maybe I would like to implement another smart pointer b_ptr
, which would give me 6 versions for every comparison operator (since I want it to also work with a_ptr
), clearly not manageable.
Is there any way to get around this problem?
EDIT:
I should have probably mentioned that I want to create wrappers around smart pointers, in which case this question makes more sense, e.g.
template<typename T>
class a_ptr
{
public:
const T* get() const {return p_.get();}
private:
std::shared_ptr<T> p_;
};
template<typename T>
class b_ptr
{
public:
const T* get() const {return p_.get();}
private:
a_ptr<T> p_;
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
如果其中任何一个(除了比较两个
a_ptr
的那个)成立,那么您的程序就有错误。所以,就扔掉它吧。智能指针之所以聪明,是因为它负责管理其背后的内存。而且你不能让两个不同的智能指针来管理一块内存。考虑
unique_ptr
和shared_ptr
。一旦拥有的智能指针被销毁,指针就会被销毁。仅当所有拥有的智能指针都被销毁时,第二个才会销毁指针。我认为很明显它会很快导致双重删除和其他有趣的事情。If any of these, except the one comparing two
a_ptr
, ever hold true, your program has a bug. So, just drop it. Smart pointer is smart, because it's responsible of managing the memory behind it. And you just cannot have two different smart pointers managing one piece of memory.Consider
unique_ptr
andshared_ptr
. One destroys the pointer as soon as the owning smart pointer is destroyed. Second destroys the pointer only when all owning smart pointers are destroyed. I think it's fairly obvious it would quickly lead to double deletes and other fun stuff.本·沃伊特(Ben Voigt)走在正确的道路上——当然,除了我们没有概念。
它必须位于
a_ptr
和b_ptr
的同一命名空间中,以便 ADL 启动(因此,如果它们位于不同的命名空间中,则每个命名空间需要每个运算符的一个版本)。魔法特性有多种发挥作用的可能性。从概念上讲,最简单的一个是拥有一个专门针对您关心的每种指针类型的特征:
更复杂的特征将检查该类型是否支持
get
成员。实际上,我们不需要为此提供特质!这个简单的运算符将被 ADL 选取,但如果其中一种类型不支持
get
,或者比较不起作用,则 SFINAE 本身会被排除。Ben Voigt is on the right track -- except of course we don't have concepts.
This must be in the same namespace of
a_ptr
andb_ptr
for ADL to kick (so if they are in separate namespaces you need one version of each operator for each namespace).There are several possibilities for the magic trait to work. The one that is conceptually the simplest is to have a trait that is specialized for each pointer type you care about:
A more elaborate trait would check that the type supports a
get
member. Actually, we don't need a trait for that!This simple operator will be picked up by ADL, except that it will SFINAE itself out if one of the type doesn't support
get
, or if the comparison doesn't work.怎么样:
...
由于 SFINAE,
decltype
位拒绝非指针。unwrap_ptr
帮助器使指针访问的语法同质化,其复杂性仅与指针类型的数量成线性关系。How about:
...
The
decltype
bit rejects non-pointers due to SFINAE. And theunwrap_ptr
helper homogenizes the syntax for pointer access, with complexity only linear in the number of pointer types.您可以只标记智能指针类型,然后实现一个通用版本,该版本至少依赖于要标记的传递参数之一:
You can just tag your smart pointer types and then implement a generic version which relies on at least one of the passed arguments to be tagged:
您可以从现有智能指针继承自定义智能指针。这样您就根本不需要实现任何运算符。
也正如猫加加所说。您不能有两个智能指针管理一块内存。因此,如果您正在实现智能指针,您应该确保这是正确的。您应该将
operator=
设为私有,这样就无法将其复制到其他位置。You could inherit your custom smart pointer from an existing smart pointer. This way you won't have to implement any operators at all.
Also as as Cat Plus Plus said. You cannot have two smart pointer managing one piece of memory. So If you're implementing a smart pointer you should make sure that holds true. You should make
operator=
private so it cannot be copied into another location.它可能与为智能指针编写 sfinae 特征一样困难。一旦你得到它,解决方案就非常简单了,你不需要 c++11:
并且由于 std::shared_ptr 已经有运算符 ==,你需要将比较运算符放在同一个命名空间中,其中您的智能指针类型是。
It can be as difficult as writing a sfinae trait for smart pointers. As soon as you get it, the solution is pretty straight forward, you don't need c++11 for this:
And since std::shared_ptr already have operator==, you need to put your comparison operator in the same namespace where your smart pointer type is.