473,396 Members | 2,111 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

C++ standard and current implementation

I the C++ standard page 472 it says that an associative container can be
constructed like X(i,j,c) where i and j are input iterators to elements.
But in the implementation there is no constructor that matches this
requirement, the only constructors are:

public:
// allocation/deallocation
_Rb_tree()
{ }

_Rb_tree(const _Compare& __comp)
: _M_impl(allocator_type(), __comp)
{ }

_Rb_tree(const _Compare& __comp, const allocator_type& __a)
: _M_impl(__a, __comp)
{ }

_Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>& __x)
: _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare)
{
if (__x._M_root() != 0)
{
_M_root() = _M_copy(__x._M_begin(), _M_end());
_M_leftmost() = _S_minimum(_M_root());
_M_rightmost() = _S_maximum(_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
}
}

~_Rb_tree()
{ _M_erase(_M_begin()); }

How does the implementation meet this requirement when the constructor
is not implemented?
Jun 11 '07 #1
7 2040
desktop wrote:
I the C++ standard page 472 it says that an associative container can be
constructed like X(i,j,c) where i and j are input iterators to elements.
But in the implementation there is no constructor that matches this
requirement, the only constructors are:

public:
// allocation/deallocation
_Rb_tree()
{ }

_Rb_tree(const _Compare& __comp)
: _M_impl(allocator_type(), __comp)
{ }

_Rb_tree(const _Compare& __comp, const allocator_type& __a)
: _M_impl(__a, __comp)
{ }

_Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>& __x)
: _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare)
{
if (__x._M_root() != 0)
{
_M_root() = _M_copy(__x._M_begin(), _M_end());
_M_leftmost() = _S_minimum(_M_root());
_M_rightmost() = _S_maximum(_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
}
}

~_Rb_tree()
{ _M_erase(_M_begin()); }

How does the implementation meet this requirement when the constructor
is not implemented?
Nowhere in any part of the standard does it mention the class _Rb_tree,
much less that it satisfies the requirements for an associative container.

_Rb_tree is at most an implementation detail of your specific
implementation. There isn't much of a compelling reason to be digging
around through it unless you are observing some specific incorrect
behavior in your implementation.

--
Alan Johnson
Jun 11 '07 #2
Alan Johnson wrote:
desktop wrote:
>I the C++ standard page 472 it says that an associative container can
be constructed like X(i,j,c) where i and j are input iterators to
elements. But in the implementation there is no constructor that
matches this requirement, the only constructors are:

public:
// allocation/deallocation
_Rb_tree()
{ }

_Rb_tree(const _Compare& __comp)
: _M_impl(allocator_type(), __comp)
{ }

_Rb_tree(const _Compare& __comp, const allocator_type& __a)
: _M_impl(__a, __comp)
{ }

_Rb_tree(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>& __x)
: _M_impl(__x.get_allocator(), __x._M_impl._M_key_compare)
{
if (__x._M_root() != 0)
{
_M_root() = _M_copy(__x._M_begin(), _M_end());
_M_leftmost() = _S_minimum(_M_root());
_M_rightmost() = _S_maximum(_M_root());
_M_impl._M_node_count = __x._M_impl._M_node_count;
}
}

~_Rb_tree()
{ _M_erase(_M_begin()); }

How does the implementation meet this requirement when the constructor
is not implemented?

Nowhere in any part of the standard does it mention the class _Rb_tree,
much less that it satisfies the requirements for an associative container.

_Rb_tree is at most an implementation detail of your specific
implementation. There isn't much of a compelling reason to be digging
around through it unless you are observing some specific incorrect
behavior in your implementation.

But how is it out of curiosity that the following works:

std::vector<inthh;
hh.push_back(1);
hh.push_back(2);
hh.push_back(3);
std::vector<int>::iterator it1 = hh.begin();
std::vector<int>::iterator it2 = hh.end();
std::set<intmy_set(it1,it2);

when there is no matching constructor for (it1,it2) in the above
implementation on my system.
Jun 11 '07 #3
On 11 Jun, 09:14, desktop <f...@sss.comwrote:
Alan Johnson wrote:
desktop wrote:
I the C++ standard page 472 it says that an associative container can
be constructed like X(i,j,c) where i and j are input iterators to
elements. But in the implementation there is no constructor that
matches this requirement, the only constructors are:
<snip part of implementation specific _Rb_tree class>
How does the implementation meet this requirement when the constructor
is not implemented?
Nowhere in any part of the standard does it mention the class _Rb_tree,
much less that it satisfies the requirements for an associative container.
_Rb_tree is at most an implementation detail of your specific
implementation. There isn't much of a compelling reason to be digging
around through it unless you are observing some specific incorrect
behavior in your implementation.

But how is it out of curiosity that the following works:

std::vector<inthh;
hh.push_back(1);
hh.push_back(2);
hh.push_back(3);
std::vector<int>::iterator it1 = hh.begin();
std::vector<int>::iterator it2 = hh.end();
std::set<intmy_set(it1,it2);

when there is no matching constructor for (it1,it2) in the above
implementation on my system.
There is a matching constructor, you just haven't found it yet. Note
that this is straying into the off-topic implementation details of
your particular compiler, but if you want to find the constructor, you
could try stepping into it with your debugger.

The best people to ask about *how* your particular compiler implements
the standard library is a group dedicated to that compiler.

Gavin Deane

Jun 11 '07 #4
On 6/11/2007 10:45 AM, Gavin Deane wrote:
On 11 Jun, 09:14, desktop <f...@sss.comwrote:
>Alan Johnson wrote:
>>desktop wrote:
I the C++ standard page 472 it says that an associative container can
be constructed like X(i,j,c) where i and j are input iterators to
elements. But in the implementation there is no constructor that
matches this requirement, the only constructors are:

<snip part of implementation specific _Rb_tree class>
>>>How does the implementation meet this requirement when the constructor
is not implemented?
Nowhere in any part of the standard does it mention the class _Rb_tree,
much less that it satisfies the requirements for an associative container.
_Rb_tree is at most an implementation detail of your specific
implementation. There isn't much of a compelling reason to be digging
around through it unless you are observing some specific incorrect
behavior in your implementation.
But how is it out of curiosity that the following works:

std::vector<inthh;
hh.push_back(1);
hh.push_back(2);
hh.push_back(3);
std::vector<int>::iterator it1 = hh.begin();
std::vector<int>::iterator it2 = hh.end();
std::set<intmy_set(it1,it2);

when there is no matching constructor for (it1,it2) in the above
implementation on my system.

There is a matching constructor, you just haven't found it yet. Note
that this is straying into the off-topic implementation details of
your particular compiler, but if you want to find the constructor, you
could try stepping into it with your debugger.
What about this constructor:

template <class InputIterator>
set(InputIterator start, InputIterator finish,
const Compare& comp = Compare()
const Allocator& alloc = Allocator());

??

Regards,
Stefan
--
Stefan Naewe stefan dot naewe at atlas-elektronik dot com
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html
Plain text mails only, please http://www.expita.com/nomime.html
Jun 11 '07 #5
Stefan Naewe wrote:
On 6/11/2007 10:45 AM, Gavin Deane wrote:
>On 11 Jun, 09:14, desktop <f...@sss.comwrote:
>>Alan Johnson wrote:
desktop wrote:
I the C++ standard page 472 it says that an associative container can
be constructed like X(i,j,c) where i and j are input iterators to
elements. But in the implementation there is no constructor that
matches this requirement, the only constructors are:
<snip part of implementation specific _Rb_tree class>
>>>>How does the implementation meet this requirement when the constructor
is not implemented?
Nowhere in any part of the standard does it mention the class _Rb_tree,
much less that it satisfies the requirements for an associative container.
_Rb_tree is at most an implementation detail of your specific
implementation. There isn't much of a compelling reason to be digging
around through it unless you are observing some specific incorrect
behavior in your implementation.
But how is it out of curiosity that the following works:

std::vector<inthh;
hh.push_back(1);
hh.push_back(2);
hh.push_back(3);
std::vector<int>::iterator it1 = hh.begin();
std::vector<int>::iterator it2 = hh.end();
std::set<intmy_set(it1,it2);

when there is no matching constructor for (it1,it2) in the above
implementation on my system.
There is a matching constructor, you just haven't found it yet. Note
that this is straying into the off-topic implementation details of
your particular compiler, but if you want to find the constructor, you
could try stepping into it with your debugger.

What about this constructor:

template <class InputIterator>
set(InputIterator start, InputIterator finish,
const Compare& comp = Compare()
const Allocator& alloc = Allocator());

??

Regards,
Stefan
Thanks that gave me a hint to how it work it works. First you call the
set constructor:

/**
* @brief Builds a %set from a range.
* @param first An input iterator.
* @param last An input iterator.
*
* Create a %set consisting of copies of the elements from first,last).
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
template<class _InputIterator>
set(_InputIterator __first, _InputIterator __last)
: _M_t(_Compare(), allocator_type())
{ _M_t.insert_unique(__first, __last); }

Which calls insert_unique in the underlying associative container:

template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
template<class _II>
void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
::insert_unique(_II __first, _II __last) {
for ( ; __first != __last; ++__first)
insert_unique(*__first);
}

this is basically a loop that calls insert with content of the iterator
until it reaches the end of the sequence.

Since the complexity is linear when the sequence is sorted it must rely
on the fact that a sorted sequence only yields a constant number of re
balancing operations.
Jun 11 '07 #6
On Jun 11, 11:46 am, desktop <f...@sss.comwrote:
Stefan Naewe wrote:
[...]
Thanks that gave me a hint to how it work it works. First you call the
set constructor:
/**
* @brief Builds a %set from a range.
* @param first An input iterator.
* @param last An input iterator.
*
* Create a %set consisting of copies of the elements from first,last).
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
template<class _InputIterator>
set(_InputIterator __first, _InputIterator __last)
: _M_t(_Compare(), allocator_type())
{ _M_t.insert_unique(__first, __last); }
Which calls insert_unique in the underlying associative container:
template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
template<class _II>
void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
::insert_unique(_II __first, _II __last) {
for ( ; __first != __last; ++__first)
insert_unique(*__first);
}
this is basically a loop that calls insert with content of the iterator
until it reaches the end of the sequence.
Since the complexity is linear when the sequence is sorted it must rely
on the fact that a sorted sequence only yields a constant number of re
balancing operations.
The number of rebalancing operations is irrelevant to the
complexity, which is, if I'm not mistaken, expressed in number
of comparison operations. And at least on the implementation I
have access to, this overload of insert_unique is:

template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>
void
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
_M_insert_unique(_II __first, _II __last)
{
for (; __first != __last; ++__first)
_M_insert_unique(end(), *__first);
}

Note the first argument to the nested function. It's a "hint"
as to where the user thinks the element should go, and if the
element actually does belong there, insertion can be done with a
constant number of comparisons, just enough to ensure that the
hint is correct.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 11 '07 #7
James Kanze wrote:
On Jun 11, 11:46 am, desktop <f...@sss.comwrote:
>Stefan Naewe wrote:

[...]
>Thanks that gave me a hint to how it work it works. First you call the
set constructor:
>/**
* @brief Builds a %set from a range.
* @param first An input iterator.
* @param last An input iterator.
*
* Create a %set consisting of copies of the elements from first,last).
* This is linear in N if the range is already sorted, and NlogN
* otherwise (where N is distance(first,last)).
template<class _InputIterator>
set(_InputIterator __first, _InputIterator __last)
: _M_t(_Compare(), allocator_type())
{ _M_t.insert_unique(__first, __last); }
>Which calls insert_unique in the underlying associative container:
>template <class _Key, class _Val, class _KoV, class _Cmp, class _Alloc>
template<class _II>
void _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>
::insert_unique(_II __first, _II __last) {
for ( ; __first != __last; ++__first)
insert_unique(*__first);
}
>this is basically a loop that calls insert with content of the iterator
until it reaches the end of the sequence.
>Since the complexity is linear when the sequence is sorted it must rely
on the fact that a sorted sequence only yields a constant number of re
balancing operations.

The number of rebalancing operations is irrelevant to the
complexity, which is, if I'm not mistaken, expressed in number
of comparison operations. And at least on the implementation I
have access to, this overload of insert_unique is:

template<typename _Key, typename _Val, typename _KoV,
typename _Cmp, typename _Alloc>
template<class _II>
void
_Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>::
_M_insert_unique(_II __first, _II __last)
{
for (; __first != __last; ++__first)
_M_insert_unique(end(), *__first);
}

Note the first argument to the nested function. It's a "hint"
as to where the user thinks the element should go, and if the
element actually does belong there, insertion can be done with a
constant number of comparisons, just enough to ensure that the
hint is correct.
Ok and when the sequence is sorted calling insert with a hint always
yields a constant number of comparisons.
Jun 11 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Raymond Hettinger | last post by:
Comments are invited on the following proposed PEP. Raymond Hettinger ------------------------------------------------------- PEP: 329
88
by: Matt | last post by:
Hi folks. Can you help with some questions? I gather that some types supported by g++ are nonstandard but have been proposed as standards. Are the long long and unsigned long long types still...
29
by: David Eng | last post by:
In replying to P.J. Plauger (...
43
by: Steven T. Hatton | last post by:
Now that I have a better grasp of the scope and capabilities of the C++ Standard Library, I understand that products such as Qt actually provide much of the same functionality through their own...
0
by: Gregory Pietsch | last post by:
Hello comp.lang.c enthusiasts, Once while in a fit of pique, I thought I'd pull a Plauger. I have come up with an implementation of the functions declared in the standard C99 header fenv.h. I...
32
by: toolmaster | last post by:
Since many of the modern computer languages have built-in namespace features, I can't understand why not add this feature into standard C. I've heard many people complain of the lacking of...
52
by: lovecreatesbeauty | last post by:
Why the C standard committee doesn't provide a standard implementation including the C compiler and library when the language standard document is published? C works on the abstract model of low...
21
by: Kannan | last post by:
Its been a while I have done pure C programming (I was coding in C++). Is the following function valid according to standard C? int main(int argc, char *argv) { int x; x = 9; printf("Value...
4
by: dustin | last post by:
I've been hacking away on this PEP for a while, and there has been some related discussion on python-dev that went into the PEP: ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.