【发布时间】:2021-08-31 14:21:11
【问题描述】:
我有一个智能指针的类模板,我想要一个 operator+()
template<typename T, typename U>
class Foo{};
template<typename T, typename U>
std::unique_ptr<Foo<T,U>> operator+(std::shared_ptr<const Foo<T, U>>, std::shared_ptr<const Foo<T, U>>);
我现在希望以下内容与 tempate 参数推导一起使用:
std::shared_ptr<Foo<T, U>> a, b, c;
auto d = a + b + c;
当然不是,因为a 和b 是指向非const 的指针,而不是指向const 的指针。它也不起作用,因为a + b 是唯一指针而不是共享指针。
是否有一个优雅的解决方案可以使这种推论发挥作用?使用运算符,我真的不想明确指定模板参数。我看到的唯一可行的方法是对shared_ptr 和unique_ptr 以及const 和非常量的所有排列重载operator+,但要编写16 个函数定义。
【问题讨论】:
-
你为什么要那个,而不是
*d = *a + *b + *c?也就是为什么要这些类型的语义与其他指针类型的语义不一致? -
这听起来像是一个 XY 问题。将两个指针相加是什么意思?那有什么作用?很可能这不是一个简单的添加,您应该使用命名函数,然后它会给您
auto d = named_function(c, named_function(a, b)。也就是说,我宁愿有一个函数通过引用获取底层对象 (Foo<T, U>),那么你不必担心 const 与否,你可以像auto d = named_function(*c, named_function(*a, *b)一样调用它 -
这两个 cmets 的答案是,我一直在努力在
Foo几乎总是以指向 const 的共享指针的形式存在的上下文中寻求一个干净方便的接口。取消引用 sum 中的每个参数或链接命名函数在我看来根本不那么干净。然而,我理解,如果添加两个指针与添加两个值具有完全相同的语义,它确实可能会导致更多的混乱而不是方便,所以我可能会选择一个采用 const refs 的函数。 -
如果您通常使用指向 const 的共享指针,并且如果创建新对象时没有大张旗鼓(例如在计算算术表达式时),那么您可能正在尝试实现 flyweight或某种copy on write 对象。这不是您应该尝试使用运算符重载技巧的那种事情。
标签: c++ template-argument-deduction