[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

STL Set Element Ordering Relationship for Boost Shared_Ptr

Posted on 2011-05-13
2
Medium Priority
?
601 Views
Last Modified: 2012-05-11
Hi,

I wanted to see how boost shared_ptr works hence I copied one example code snippet from boost documentation and was testing it. I have attached it here. I tested it on windows with visual studio 2010 IDE. If you compile and check the output, you will see that if we insert elements just in to "set", it is getting inserted and automatically sorted. But the moment we try to insert same elements in vector, approximately after 3rd element, the order of insertion changes. Also, duplicate values are getting inserted without any problem. Destruction odrer looks fine.

My questions are -

1. Is this behavior because we are storing shared_ptr objects? Is it sorting based on pointers?  
2. Is vector push_back really affecting insertion mechanism of "set"?
3. How exactly "reset" works? Does it create multiple copies or just adds to reference counting?
4. How can I ensure that elements (shared_ptr type) are inserted in the order of insertion or sorted based on value?
5. How can "set" avoid inserting duplicate element which is expected since its the natural behaviour and works when we insert primitive types?

Any relevants links will be appreciated.

The output of attached program looks like below  -

Inserted 1
1

Inserted 5
1
5

Inserted 6
1
5
6

Inserted 3
1
5
3
6

Inserted 4
1
5
3
6
4

Inserted 2
1
5
3
6
4
2

Inserted 3 again
1
5
3
6
4
2
3

Size of Foo set is ----> 7

Destructing Foo 3
Destructing Foo 2
Destructing Foo 4
Destructing Foo 6
Destructing Foo 3
Destructing Foo 5
Destructing Foo 1

Thanks.

 
#include <vector>
#include <set>
#include <iostream>
#include <algorithm>
#include <boost/shared_ptr.hpp>

using namespace std;

struct Foo {
	Foo(int x_) : x(x_) {
	}
	~Foo() {
		cout << "Destructing Foo " << x << endl;
	}


	int x;
};

typedef boost::shared_ptr<Foo> Foo_Ptr;

struct FooPtrOps {

	void operator () (const Foo_Ptr & a) {
		cout << a->x << endl;
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	set<Foo_Ptr> foo_set;
	vector<Foo_Ptr> foo_vec;

	Foo_Ptr fooptr (new Foo(1) );
	foo_vec.push_back(fooptr);
	foo_set.insert(fooptr);

	cout << "Inserted 1\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	fooptr.reset( new Foo(5) );
	foo_vec.push_back(fooptr);
	foo_set.insert(fooptr);

	cout << "Inserted 5\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	fooptr.reset( new Foo(6) );
	foo_vec.push_back(fooptr);
	foo_set.insert(fooptr);

	cout << "Inserted 6\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	fooptr.reset( new Foo(3) );
	foo_set.insert(fooptr);

	cout << "Inserted 3\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	fooptr.reset( new Foo(4) );
	foo_set.insert(fooptr);

	cout << "Inserted 4\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	fooptr.reset( new Foo(2) );
	foo_set.insert(fooptr);

	cout << "Inserted 2\n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	//Adding duplicate of 3
	fooptr.reset( new Foo(3) );
	foo_set.insert(fooptr);

	cout << "Inserted 3 again \n";
	for_each(foo_set.begin(), foo_set.end (), FooPtrOps());
	cout << "\n";

	cout << "Size of Foo set is ----> " << foo_set.size() << "\n" << endl ;

	return 0;
}

Open in new window

0
Comment
Question by:James Bond
2 Comments
 
LVL 53

Accepted Solution

by:
Infinity08 earned 2000 total points
ID: 35752859
>> 1. Is this behavior because we are storing shared_ptr objects? Is it sorting based on pointers?  

Indeed. If you want to sort on a different criterium, you'll need to provide a comparator when constructing the set (see http://www.cplusplus.com/reference/stl/set/set/ for an example).


>> 2. Is vector push_back really affecting insertion mechanism of "set"?

No.

>> 3. How exactly "reset" works? Does it create multiple copies or just adds to reference counting?

The reset member function of boost::shared_ptr replaces the current pointer with a new one. This decrements the reference count by one for the old pointer, and increments it by one for the new pointer.

>> 4. How can I ensure that elements (shared_ptr type) are inserted in the order of insertion or sorted based on value?

See my answer for 1. above.

>> 5. How can "set" avoid inserting duplicate element which is expected since its the natural behaviour and works when we insert primitive types?

See my answer for 1. above.
0
 

Author Comment

by:James Bond
ID: 35752990
Thanks infinity08. It works that way.

For others benefit this is what I did. I added below method in struct FooPtrOps -

 bool operator()( const Foo_Ptr & a, const Foo_Ptr & b )
    { return a->x < b->x; }

And while constructing set container, I added FooPtrOps as 2nd parameter -

set<Foo_Ptr, FooPtrOps > foo_set;

Thats it.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question