为什么 std::sub_match公开继承 std::pair?
我正在阅读 std::sub_match
的文档,发现它公开继承自 std::pair
。由于 sub_match
只是一对字符序列的迭代器,带有一些附加功能,我可以理解它是用 pair
实现的,但为什么要使用公共继承?
从 std::pair
公开继承的问题与从大多数其他标准类公开继承的问题相同:它们并不意味着可以进行多态操作(特别是它们没有定义虚拟类)析构函数)。其他成员也将无法正常工作,即赋值运算符和交换成员函数(它们不会复制sub_match
的matched
成员)。
为什么 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一个有趣的问题。据推测,他们认为这是安全的
因为无论如何没有人会动态分配一个。关于
获取
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 valuefrom some of the functions of
basic_regex
, or as copies of othersub_match
, and all of these will be either temporaries or localvariables.
Note that it's not safe to keep
sub_match
objects around anyway, sincethey contain iterators whose lifetime... doesn't seem to be specified in
the standard. Until the
match_results
object is reused? Until thestring
operand to the function which filled in thematch_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
.因为C++没有办法在没有公共继承的情况下继承接口。您可以通过私有继承来继承实现,但所有内容都是私有的。如果您想要与
std::pair
相同的接口,则必须成为std::pair
。另外,请考虑这一点。这显然是未定义的行为:
但这也是如此:
为什么第一个比第二个更值得关注?
sub_match
和pair
是轻量级对象(当然取决于它们的内容)。它们旨在通过引用进行复制或传递,所有这些都是 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 astd::pair
.Also, consider this. This is obviously undefined behavior:
But so is this:
Why is the first one so much more of a concern than the second?
sub_match
andpair
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.以下是
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_discussionNothing 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 fromregex
function. Moreover pairs of iterators are a very practical way of implementing ranges.因为他们不需要虚拟析构函数? ;-)
Because they didn't need virtual destructor? ;-)
如果
std::sub_match
没有自己的状态,那么它可以从std::pair
继承。不过不要在家里做。If
std::sub_match<BidirectionalIterator>
has no state of its own, then it is fine for it to inherit fromstd::pair
. Don't do it at home though.