为什么没有 bool std::operator==(T1* a, std::shared_ptr b) 的重载<T2>?
Why is there no overload of bool std::operator==(T1* a, std::shared_ptr<T2> b)?
我注意到标准库没有为shared_ptr
和原始指针的相等操作符提供重载。如果您有一个std::unordered_set<std::shared_ptr<Foo>>
,并且希望通过传递原始的Foo*
没有这样的过载有什么具体的原因吗?在我看来,这很容易实现:
template<typename T1, typename T2>
bool operator==(const T1 * a, const std::shared_ptr<T2> & b) {
return a == b.get();
}
…这个实现会有什么危险或意想不到的地方吗?
对于unordered_set
,您需要的不仅仅是==
,还需要hash
才能工作。
对于set
,透明比较器允许您根据非键类型的内容查找内容。默认情况下,set
不是透明的,所以这个操作符不起作用。
一旦您添加了自己的比较器,您就可以覆盖==
。
遗憾的是,unordered_set
目前没有透明选项。为了在unordered_set
中查找/擦除/等内容,必须具有密钥类型。
你的超载是有问题的。更好的方法是:
template<class U, class...Ts>
auto operator==( U const* lhs, std::shared_ptr<Ts...> const& rhs )->decltype( lhs == rhs.get() ) {
return lhs == rhs.get();
}
template<class U, class...Ts>
auto operator==( std::shared_ptr<Ts...> const& lhs, U const* rhs )->decltype( lhs.get() == rhs ) {
return lhs.get() == rhs;
}
,但请注意,合理地编写上述代码需要c++ 11支持。缺少上述解决方案的最终结果要么是(使用SFINAE)编写混乱,要么声称在没有的类型之间存在==
(并且对于其他SFINAE代码实现它来说已经太晚了)。
但是<
呢?好吧,原始指针上的<
只在同一个对象中是一个好主意,所以在共享指针和原始指针之间公开它似乎是一个可怕的想法。所以现在我们正在接近std::less
,并希望在智能指针和非智能指针之间增加透明支持。
我们是否也支持混合智能指针(shared
和unique
?)——天真地,你可能会说不,但是如果你替换了删除器,unique_ptr
并不一定要表示内存所有权!(shared_ptr
也是如此)。具有不同删除器的智能指针应该被认为是相等的还是等价的?根据删除器的不同,数据的含义可能会有很大的不同。
现在,考虑到我已经设法从几分钟的工作中提出了棘手的问题,和这样的过载会鼓励原始指针和shared_ptr
混合使用,和甚至不能帮助解决您想要解决的问题,也许这不是一个好主意。
也许是。这就是为什么它不符合标准的真正原因。
没有人提出,也没有人接受。
如果你认为这是一个好主意,我鼓励你看看提案的过程。检查其他的提案,找出正确的步骤,然后把提案放在一起。
如果这看起来太吓人,您可能想要创建一个提供上述比较操作符的健壮库,并将其添加到boost中,也许人们会使用它并说"哇,我们一直需要它!"
如果您正在使用shared_ptr,传递原始指针是非常危险的,因为如果您有保存原始指针的东西,根据定义,它会破坏引用计数的shared_ptr概念。没有重载的原因可能是为了阻止这种情况。
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- std::vector 没有重载函数的实例与参数列表匹配
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 重载 + 自己的类和 std::string 的运算符
- 使用重载 [] 运算符返回 std::map() 的可赋值
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 重载 std::字符串运算符+ 用于打印枚举名称
- 具有std::initializer_list参数的非成员函数(/non构造函数上下文)的重载解析
- C++派生类重载函数(带有 std::function 参数)不可见
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- C++:从重载函数转换为 std::function
- msvc 编译器(和其他编译器)如何知道要绑定到哪个 std 重载?
- 关于在成员重载中使用 std::move() 的问题
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- 在 std::visit 中跳过变体类型的一些重载组合的方法是什么?
- std::begin-类型特征中未考虑用户定义的重载