为什么 std::sub_match公开继承 std::pair?

发布于 2024-12-12 00:19:36 字数 609 浏览 0 评论 0原文

我正在阅读 std::sub_match 的文档,发现它公开继承自 std::pair。由于 sub_match 只是一对字符序列的迭代器,带有一些附加功能,我可以理解它是用 pair 实现的,但为什么要使用公共继承?

std::pair 公开继承的问题与从大多数其他标准类公开继承的问题相同:它们并不意味着可以进行多态操作(特别是它们没有定义虚拟类)析构函数)。其他成员也将无法正常工作,即赋值运算符和交换成员函数(它们不会复制sub_matchmatched成员)。

为什么 Boost 开发人员和委员会决定通过从 pair 公开继承来实现 sub_match,而不是使用组合(或者如果他们想通过以下方式保留成员访问权限,则使用带有 using 声明的私有继承) 第一第二)?

I was reading the documentation of std::sub_match<BidirectionalIterator> and saw that it publicly inherits from std::pair<BidirectionalIterator, BidirectionalIterator>. Since a sub_match is simply a pair of iterators into a sequence of characters, with some additional functions, I can understand that it is implemented with a pair, but why use public inheritance?

The problem with inheriting publicly from std::pair<T,U> is the same as inheriting publicly from most other standard classes: they are not meant to be manipulated polymorphically (notably they do not define a virtual destructor). Other members will also fail to work properly, namely the assignment operator and the swap member function (they will not copy the matched member of sub_match).

Why did Boost developers and then the committee decided to implement sub_match by inheriting publicly from pair instead of using composition (or private inheritance with using declarations if they wanted to keep member access through first and second)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

手心的海 2024-12-19 00:19:36

这是一个有趣的问题。据推测,他们认为这是安全的
因为无论如何没有人会动态分配一个。关于
获取 sub_match 对象的唯一方法是作为返回值
来自 basic_regex 的一些函数,或者作为其他函数的副本
sub_match,所有这些都将是临时的或本地的
变量。

请注意,无论如何保留 sub_match 对象都是不安全的,因为
它们包含迭代器,其生命周期...似乎没有指定
标准。直到重用 match_results 对象为止?直到
填充 match_results 的函数的 string 操作数
对象被破坏?或者?

我仍然会避免公共继承。但在这种情况下,它是
并不像看起来那么危险,因为你真的没有理由
曾经想要动态分配sub_match

It's an interesting question. Presumably, they considered it safe
because no one would ever dynamically allocate one anyway. About the
only way you're going to get sub_match objects is as a return value
from some of the functions of basic_regex, or as copies of other
sub_match, and all of these will be either temporaries or local
variables.

Note that it's not safe to keep sub_match objects around anyway, since
they contain iterators whose lifetime... doesn't seem to be specified in
the standard. Until the match_results object is reused? Until the
string operand to the function which filled in the match_results
object is destructed? Or?

I'd still have avoided the public inheritence. But in this case, it's
not as dangerous as it looks, because there's really no reason you'd
ever want to dynamically allocate a sub_match.

我的奇迹 2024-12-19 00:19:36

因为C++没有办法在没有公共继承的情况下继承接口。您可以通过私有继承来继承实现,但所有内容都是私有的。如果您想要与 std::pair 相同的接口,则必须成为 std::pair

另外,请考虑这一点。这显然是未定义的行为:

std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch;
delete pMatch;

但这也是如此:

std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch.pair;
delete pMatch;

为什么第一个比第二个更值得关注?

sub_matchpair 是轻量级对象(当然取决于它们的内容)。它们旨在通过引用进行复制或传递,所有这些都是 100% 安全的。几乎没有理由在堆上分配它们并通过指针使用它们。因此,虽然我理解您的担忧,但我认为这在任何实际代码中都不太可能发生。

Because C++ has no way to inherit an interface without public inheritance. You can inherit an implementation with private inheritance, but then everything is private. If you want the same interface as a std::pair, you have to be a std::pair.

Also, consider this. This is obviously undefined behavior:

std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch;
delete pMatch;

But so is this:

std::sub_match<BidirectionalIterator> theMatch = ...;
std::pair<BidirectionalIterator> *pMatch = &theMatch.pair;
delete pMatch;

Why is the first one so much more of a concern than the second?

sub_match and pair are light-weight objects (depending on their contents of course). They are meant to be copied or passed by reference, all of which is 100% safe. There is little if any reason to allocate them on the heap and use them through pointers. So while I understand your concern, I think it's unlikely to happen in any real code.

淡紫姑娘! 2024-12-19 00:19:36

以下是 regex 的作者对此的看法:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm#matches_discussion

恐怕您的问题没有什么具体内容。

我猜想这个决定是重新发明轮子和引入一点误用风险之间的权衡。请注意,通常不需要构造 sub_match,它们是从 regex 函数返回的。此外,成对的迭代器是实现范围的一种非常实用的方法。

Here's what regex's author has to say about it: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1429.htm#matches_discussion

Nothing very specific to your question, I'm afraid.

I would guess that this decision was a trade off between reinventing the wheel and introducing a little risk of misuse. Note that in general there is no need to construct a sub_match, they are returned from regex function. Moreover pairs of iterators are a very practical way of implementing ranges.

ζ澈沫 2024-12-19 00:19:36

因为他们不需要虚拟析构函数? ;-)

Because they didn't need virtual destructor? ;-)

执手闯天涯 2024-12-19 00:19:36

如果 std::sub_match 没有自己的状态,那么它可以从 std::pair 继承。不过不要在家里做。

If std::sub_match<BidirectionalIterator> has no state of its own, then it is fine for it to inherit from std::pair. Don't do it at home though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文