is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} };
struct Des { bool operator()(int a, int b) {return b > a;} };
int main() {
int arr[] = {1, 2, 3};
set<int,Asc> asc(arr, arr+3);
set<int,Des>::i terator beg = asc.begin(); //[*]
set<int,Des>::i terator end = asc.end(); //[*]
copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123
return 0;
}
note that the types of the _sets_ in both sides of assignment[*] are
different due to their different comparators (Asc/Des). nevertheless,[*] seems to be standard as the template parameters of the iterator
are 'Key' and 'Distance' (not the 'Comparator'), and so the iterator
types are equal, right? [we use user defined template 'Comparator'
parameters (Des/Asc), so they don't have standard specialization,
which means we can be sure the 'Distance' type of the two iterators
is the same; the 'Key' type (int) is also obviously the same].
thanks,
--dan 13 2541
Dan Tsafrir wrote: is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
note that the types of the _sets_ in both sides of assignment[*] are different due to their different comparators (Asc/Des). nevertheless, [*] seems to be standard as the template parameters of the iterator are 'Key' and 'Distance' (not the 'Comparator'), and so the iterator types are equal, right? [we use user defined template 'Comparator' parameters (Des/Asc), so they don't have standard specialization, which means we can be sure the 'Distance' type of the two iterators is the same; the 'Key' type (int) is also obviously the same].
thanks, --dan
This code is fine. std::copy does not require that the two iterators be
of the same type. In fact, they need not even belong to containers that
hold identical types - as long as the type being copied is convertible
to the output iterator's type.
So in this example, you could copy a set<int> to a set<long> or even a
set<double> and still be OK.
Greg
Dan Tsafrir wrote: is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
Note 1: You Asc and Des functors have identical behavior.
Note 2: operator() in Asc and Des should be const methods, and
Asc and Desc should probably inherit from std::binary_fun ction<>.
e.g.:
#include <functional>
struct Asc: public std::binary_fun ction<int,int,b ool>
{
bool operator()(int a, int b) const { return a < b; }
}
struct Des: public std::binary_fun ction<int,int,b ool>
{
// assumes you didn't want identical behavior for
// Asc and Des
bool operator()(int a, int b) const { return a > b; }
}
Greg wrote: Dan Tsafrir wrote:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
This code is fine. std::copy does not require that the two iterators be of the same type. In fact, they need not even belong to containers that hold identical types - as long as the type being copied is convertible to the output iterator's type.
So in this example, you could copy a set<int> to a set<long> or even a set<double> and still be OK.
the question is not about copy(), it's about[*] (the copy() is just there
to make the program meaningful). the problem with[*] is that the program
assigns an object of the type: set<int,Asc>::i terator
to an object of the type : set<int,Dec>::i terator
thanks,
--dan
red floyd wrote: Dan Tsafrir wrote:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
Note 1: You Asc and Des functors have identical behavior.
right you are (my mistake). nevertheless, they are different types.
regardless the question is about[*] in which the program assigns an
object of the type : set<int,Asc>::i terator
to an object of the type: set<int,Dec>::i terator Note 2: operator() in Asc and Des should be const methods, and Asc and Desc should probably inherit from std::binary_fun ction<>.
e.g.:
#include <functional>
struct Asc: public std::binary_fun ction<int,int,b ool> { bool operator()(int a, int b) const { return a < b; } }
struct Des: public std::binary_fun ction<int,int,b ool> { // assumes you didn't want identical behavior for // Asc and Des bool operator()(int a, int b) const { return a > b; } }
unfortunately, this too is not related to my original question :(
--dan
Dan Tsafrir wrote: red floyd wrote: Dan Tsafrir wrote:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
Note 1: You Asc and Des functors have identical behavior.
right you are (my mistake). nevertheless, they are different types. regardless the question is about[*] in which the program assigns an object of the type : set<int,Asc>::i terator to an object of the type: set<int,Dec>::i terator
Note 2: operator() in Asc and Des should be const methods, and Asc and Desc should probably inherit from std::binary_fun ction<>.
e.g.:
#include <functional>
struct Asc: public std::binary_fun ction<int,int,b ool> { bool operator()(int a, int b) const { return a < b; } }
struct Des: public std::binary_fun ction<int,int,b ool> { // assumes you didn't want identical behavior for // Asc and Des bool operator()(int a, int b) const { return a > b; } }
unfortunately, this too is not related to my original question :(
I believe the answer is implementation-dependent depending on how
set<>::iterator is declared. If the code compiles - then the iterators
would have to be of the same type (usually declared in a red-black tree
class). Therefore since the code compiles for you, the assignments are
OK. I would just not expect them to be portable however.
Greg
Dan Tsafrir sade: is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
note that the types of the _sets_ in both sides of assignment[*] are different due to their different comparators (Asc/Des). nevertheless, [*] seems to be standard as the template parameters of the iterator are 'Key' and 'Distance' (not the 'Comparator'), and so the iterator types are equal, right? [we use user defined template 'Comparator' parameters (Des/Asc), so they don't have standard specialization, which means we can be sure the 'Distance' type of the two iterators is the same; the 'Key' type (int) is also obviously the same].
thanks, --dan
The standard defines the implementation of iterators as implementation
defined. The above code doesn't compile with RW since that
implemenation of the underlying tree class is defined as:
template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc>
class __rb_tree {
class iterator : public __it {};
};
but with STLport the class iterator is not nested within their
underlying tree class:
template <class _Value, class _Traits>
struct _Rb_tree_iterat or : public _Rb_tree_base_i terator
{ };
template <class _Key, class _Value, class _KeyOfValue, class _Compare,
_STLP_DEFAULT_A LLOCATOR_SELECT (_Value) >
class _Rb_tree : public _Rb_tree_base<_ Value, _Alloc> {
typedef _Rb_tree_iterat or<value_type, _Nonconst_trait s<value_type> >
iterator;
};
And _Compare is not used with the iterator template so your
code will compile using this implementation.
TIT
TIT wrote: Dan Tsafrir sade:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
note that the types of the _sets_ in both sides of assignment[*] are different due to their different comparators (Asc/Des). nevertheless, [*] seems to be standard as the template parameters of the iterator are 'Key' and 'Distance' (not the 'Comparator'), and so the iterator types are equal, right? [we use user defined template 'Comparator' parameters (Des/Asc), so they don't have standard specialization, which means we can be sure the 'Distance' type of the two iterators is the same; the 'Key' type (int) is also obviously the same].
thanks, --dan
The standard defines the implementation of iterators as implementation defined. The above code doesn't compile with RW since that implemenation of the underlying tree class is defined as:
template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc> class __rb_tree { class iterator : public __it {}; };
but with STLport the class iterator is not nested within their underlying tree class:
template <class _Value, class _Traits> struct _Rb_tree_iterat or : public _Rb_tree_base_i terator { };
template <class _Key, class _Value, class _KeyOfValue, class _Compare, _STLP_DEFAULT_A LLOCATOR_SELECT (_Value) > class _Rb_tree : public _Rb_tree_base<_ Value, _Alloc> {
typedef _Rb_tree_iterat or<value_type, _Nonconst_trait s<value_type> > iterator;
};
And _Compare is not used with the iterator template so your code will compile using this implementation.
TIT
Ok, I understand, it's implementation dependent.
However, wouldn't it be great had such an iterator assignment been standard?
I'm suggesting this because it would have allowed iteration over a collection
of objects sorted according to an arbitrary criterion, without the overhead of
virtual function calls:
For example, assume you have a collection of N "Job" objects sorted
according to various criteria:
set<Job,cmp_run time> s1; // holds N jobs
set<Job,cmp_arr ival> s2; // holds the same N jobs
... // etc.
And you want some loop to iterate through the job collection according
to a criterion which is specified by a user parameter 'p'. Wouldn't being
able to do the following be very beneficial in terms of performance:
set<Job>::const _iterator beg, end;
if( p == RUNTIME ) {
beg = s1.begin();
end = s1.end();
}
else if( p == ARRIVAL ) {
beg = s2.begin();
end = s2.end();
}
else if( ... ) {
// ...
} // ...
for(set<Job>::c onst_iterator i=beg; i!=end; ++i) {
// do whatever...
}
Regrettably, the only alternative I can think of that will obtain the
above, involves inheritance and virtual function calls that turn out
to be very expensive in my application (the above loop is its kernel).
What do you think? I personally can't think of any reason why the above
shouldn't be made possible/standard. Am I missing something? is there
some other simple alternative I am not aware of?
thanks,
--dan
Dan Tsafrir wrote: TIT wrote: Dan Tsafrir sade:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
note that the types of the _sets_ in both sides of assignment[*] are different due to their different comparators (Asc/Des). nevertheless, [*] seems to be standard as the template parameters of the iterator are 'Key' and 'Distance' (not the 'Comparator'), and so the iterator types are equal, right? [we use user defined template 'Comparator' parameters (Des/Asc), so they don't have standard specialization, which means we can be sure the 'Distance' type of the two iterators is the same; the 'Key' type (int) is also obviously the same].
thanks, --dan
The standard defines the implementation of iterators as implementation defined. The above code doesn't compile with RW since that implemenation of the underlying tree class is defined as:
template <class _Key, class _Val, class _KeyOf, class _Comp, class _Alloc> class __rb_tree { class iterator : public __it {}; };
but with STLport the class iterator is not nested within their underlying tree class:
template <class _Value, class _Traits> struct _Rb_tree_iterat or : public _Rb_tree_base_i terator { };
template <class _Key, class _Value, class _KeyOfValue, class _Compare, _STLP_DEFAULT_A LLOCATOR_SELECT (_Value) > class _Rb_tree : public _Rb_tree_base<_ Value, _Alloc> {
typedef _Rb_tree_iterat or<value_type, _Nonconst_trait s<value_type> > iterator;
};
And _Compare is not used with the iterator template so your code will compile using this implementation.
TIT
Ok, I understand, it's implementation dependent. However, wouldn't it be great had such an iterator assignment been standard? I'm suggesting this because it would have allowed iteration over a collection of objects sorted according to an arbitrary criterion, without the overhead of virtual function calls:
For example, assume you have a collection of N "Job" objects sorted according to various criteria:
set<Job,cmp_run time> s1; // holds N jobs set<Job,cmp_arr ival> s2; // holds the same N jobs ... // etc.
And you want some loop to iterate through the job collection according to a criterion which is specified by a user parameter 'p'. Wouldn't being able to do the following be very beneficial in terms of performance:
set<Job>::const _iterator beg, end; if( p == RUNTIME ) { beg = s1.begin(); end = s1.end(); } else if( p == ARRIVAL ) { beg = s2.begin(); end = s2.end(); } else if( ... ) { // ... } // ...
for(set<Job>::c onst_iterator i=beg; i!=end; ++i) { // do whatever... }
Regrettably, the only alternative I can think of that will obtain the above, involves inheritance and virtual function calls that turn out to be very expensive in my application (the above loop is its kernel).
What do you think? I personally can't think of any reason why the above shouldn't be made possible/standard. Am I missing something? is there some other simple alternative I am not aware of?
The Comparator is a property of the container and not its iterator. In
other words, the Container arranges the items in a particular order and
uses the Comparator to determine that order. So any iterator that
traverses the container from beginning to end will encounter each
contained item in a just one specific order. Since the items can be
sorted in only one order per container at a time, it would take more
than just a different iterator to traverse the items in a different
order.
Since the iterators of one container can be elements in another
Container, one solution would be to declare, say, a list with the
elements in one order, and then declare another list populated with the
iterators (or elements) of the first list, but sorted in a different
order. There would be some extra management involved in keeping the
sorted lists, but some savings as well gained by essentially sharing
the elements between more than one list.
Greg
"Dan Tsafrir" <da***@cs.huji. ac.il> wrote in message
news:43******** ******@cs.huji. ac.il... TIT wrote: Dan Tsafrir sade:
is the following code standard? (cleanly compiles under g++-4.0.2):
struct Asc { bool operator()(int a, int b) {return a < b;} }; struct Des { bool operator()(int a, int b) {return b > a;} }; int main() { int arr[] = {1, 2, 3}; set<int,Asc> asc(arr, arr+3); set<int,Des>::i terator beg = asc.begin(); //[*] set<int,Des>::i terator end = asc.end(); //[*] copy(beg, end, ostream_iterato r<int>(cout, "")); // prints 123 return 0; }
[...] However, wouldn't it be great had such an iterator assignment been standard? I'm suggesting this because it would have allowed iteration over a collection of objects sorted according to an arbitrary criterion, without the overhead of virtual function calls:
For example, assume you have a collection of N "Job" objects sorted according to various criteria:
set<Job,cmp_run time> s1; // holds N jobs set<Job,cmp_arr ival> s2; // holds the same N jobs ... // etc.
Would keeping the jobs in one place, and having sets of iterators work for
you application?
typedef vector<Job> Jobs;
Jobs jobs;
typedef set<Jobs::itera tor, cmp_runtime> S1;
typedef set<Jobs::itera tor, cmp_arrival> S2;
Now the iterators stored in S1 and S2 are the same type.
(Of course cmp_runtime and cmp_arrival now take Jobs::iterator types.)
And you want some loop to iterate through the job collection according to a criterion which is specified by a user parameter 'p'. Wouldn't being able to do the following be very beneficial in terms of performance:
set<Job>::const _iterator beg, end; if( p == RUNTIME ) { beg = s1.begin(); end = s1.end(); } else if( p == ARRIVAL ) { beg = s2.begin(); end = s2.end(); } else if( ... ) { // ... } // ...
for(set<Job>::c onst_iterator i=beg; i!=end; ++i) { // do whatever... }
How about :
if (p == RUNTIME)
{
for_each(s1.beg in(), /* ... */);
}
else if (/* ... */)
{
for_each(s2.beg in(), /* ... */);
}
// etc.
Ali This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Dave Benjamin |
last post by:
Hola,
I made a backport of sets.py that will run on Jython 2.1. Here is a diff
against the Python 2.3 version of sets.py. The changes were simple, but I
may have made a mistake here or there, and since the unit tests depend on
generators, it was too much trouble to try to test the module this way. I'd
appreciate any help on testing it more thoroughly. So far, everything seems
to be working fine.
The majority of the changes were due to...
|
by: Dave Benjamin |
last post by:
Hey good people,
I've been doing a lot of simultaneous Jython and CPython programming lately,
and just wanted to say, with no intended ill will toward any of the
individuals who have been generous enough to make the two languages
possible, that, well, they're kinda different.
I guess it was inevitable, but with Jython stuck at Python 2.1, it's not
really the same language as CPython is today. You still have to type "from
__future__...
|
by: Scott Smedley |
last post by:
Hi all,
I'm trying to write a special adaptor iterator for my program. I have
*almost* succeeded, though it fails under some circumstances.
See the for-loop in main().
Any pointers/help would be muchly appreciated.
Apologies for the long post - I couldn't find a shorter way to
|
by: James Stroud |
last post by:
Hello All,
I find myself in this situation from time to time: I want to compare two lists
of arbitrary objects and (1) find those unique to the first list, (2) find
those unique to the second list, (3) find those that overlap. But here is the
catch: comparison is not straight-forward. For example, I will want to
compare 2 objects based on a set of common attributes. These two objects need
not be members of the same class, etc. A function...
|
by: Lorenzo Castelli |
last post by:
This is an old problem of mine.
Basically I have an abstract base class which represents a generic iterator
over a collection of elements, and various derived classes that implement
the traversing on specific data structures.
For each iterator I want to be able to specify the four possible const
combinations, corresponding to the various void* for
pointers, with the possibility to perform conversions from non-const to
const just like...
| |
by: T.A. |
last post by:
I understand why it is not safe to inherit from STL containers, but I have
found (in SGI STL documentation) that for example bidirectional_iterator
class can be used to create your own iterator classes by inheriting from
it, ie.
class my_bidirectional_iterator : public bidirectional_iterator<double>
{
...
};
|
by: JosAH |
last post by:
Greetings,
Introduction
This week I'll write a bit about generics (those funny angular brackets). I need
an example and decided to use sets and some of their operations. This weeks'
article discusses one set class and two interesting operations on the set:
combinations and set partitioning. First a description of the algorithms is
given and then we'll have some fun with the generic implementation of them.
|
by: subramanian100in |
last post by:
I am copying the following text as it is from Stroustrup's TC++PL 3rd
edition, page 450.
It says:
"Note that a constructor given two arguments of the same type can be a
match for more than one constructor. For example,
vector<intv(10, 50); // (size, value) or (iterator1, iterator2)?
|
by: Mr.SpOOn |
last post by:
Hi,
I need a structure to represent a set of integers. I also need to
perform on this set some basic set operations, such as adding or
removing elements, joining with other sets and checking for the
presence of specific elements.
I think that using Python sets would be the best choice, but I also
need integers to be ordered inside the set and I've just found out
that, instead, Python sets are unordered collections.
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
| |
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |