4

is it possible to insert a new element to std::set like in case of std::list for example:

//insert one element named "string" to sublist of mylist

std::list< std::list<string> > mylist;
mylist.push_back(std::list<string>(1, "string"));

Now, mylist has one element of type std::string in its sub-list of type std::list.

How can you do the same in if std::set is the sub-set of std::list my list i.e

std::list<std::set <string>> mylist;

if you can't then why not?

1
  • One likely answer i'm thinking would be because a std::set doesn't accept duplicate elements, so i think you can't insert say 4 elements e.g std::set<set> (4, "string"). but there must be a way to insert at least one. Commented Mar 8, 2010 at 21:28

3 Answers 3

6

I think this should do the trick:

int main()
{
    string s = "test";
    set<string> mySet(&s, &s+1);

    cout << mySet.size() << " " << *mySet.begin();

    return 0;
}

For clarification on the legality and validity of treating &s as an array, see this discussion: string s; &s+1; Legal? UB?

Sign up to request clarification or add additional context in comments.

7 Comments

@Dave17: It works on the same principle as Kristo's post. std::set has a ctor which accepts begin- and end-iterators used to initialize the contents of the new set. I am just telling the compiler to pretend that &s+1 points to the second element in an array. A bit of a trick, but it works for the same reason Kristo's code works -- the pointer to the last element will never be dereferenced. Does that make sense?
&s+1 yields the next address after s. That would be legal if s were an array, but in this case I think it's undefined behavior. So it only appears to work correctly.
@Kristo: Yes, I was wondering about that myself. And I was prepared to accept downvotes on this if that were the case, but I'm still not sure. After all, you are doing the same thing: std::set<int> foo(&a[0], &a[5]); &a[5] doesn't exist. This usage is common throughout the STL. It is not undefined behavior because the address &a[5] is evaluated (possible because the size of each element is known at compile time), but not dereferenced. I don't see how &a[5] can be legal while at the same time &s+1 is not?
@Kristo: Put another way, &s is akin to a pointer to an array -- an array with 1 element.
@Kristo: John Dibling posted a question to get clarification on whether it's undefined behavior or not. Bottom line - a single object can be treated as an array of one element for the purposes of pointer arithmetic: stackoverflow.com/questions/2405555/string-s-s1-legal-ub
|
2

std::set doesn't have a constructor that takes an element to be inserted. The best you can do is use the range constructor:

int a[] = {1,2,3,4,5};
std::set<int> foo(a, a+5);  // insert the values 1 through 5 into foo

This version takes a begin and end iterator describing the range to be inserted into the set. You can optionally supply a sorting criterion as well. It's not quite what you wanted, but it's close. So if you had your elements stored in a container v, you can insert a new set to your list like this:

list<set<string> > myList;
myList.push_back(set<string>(v.begin(), v.end()));

Comments

0

Or, in C++0x:

    std::list<std::set<int>> foo;
    foo.push_back({1,2,3});

1 Comment

This also worked foo.push_back(set<string>({"foo","bar","quzz"}));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.