Do you use C++11

Pages: 1... 5678
xerzi wrote:
the better option would be for the function to simply take iterators.
Iterators do not guarantee access bounds, they only suggest it. You can decrement past the start iterator and increment past the end iterator if the start and end are not the start and end of the container.
darkestfright wrote:
You're not going to get better with that attitude.

I never got better when I had the other attitude of being optimistic. I've developed this attitude after years of failure.
closed account (o1vk4iN6)

It should work with arrays transparently to customer. He shouldn't do anything to make it work with arrays.


What do you mean by this, if you want it to work with arrays you'd just overload the functors.

Iterators do not guarantee access bounds, they only suggest it. You can decrement past the start iterator and increment past the end iterator if the start and end are not the start and end of the container.


Wasn't really discussing or suggesting iterators were a good design decision of the standard library but merely both solutions regardless would require iterators and simply saying one method of delivery is more flexible than the other.
Last edited on
xerzi wrote:
What do you mean by this, if you want it to work with arrays you'd just overload the functors.
THe customer is provided the function, not the functor.

xerzi wrote:
Wasn't really discussing or suggesting iterators were a good design decision of the standard library but merely both solutions regardless would require iterators and simply saying one method of delivery is more flexible than the other.
I mean the point of my challenge was that you have to live with the limitations of the function signature.
What do you mean by this, if you want it to work with arrays you'd just overload the functors.
So you want to duplicate std:begin/end behavior to avoid using std::begin/end?
You have just proved usefulness of it. You have to copy it to avoid using it.
I appreciate the effort taken by STL designers to make it useful, however I personally don't like the idea basing the design around iterators. Ok, iterators *are* a powerful and useful concept, but this doesn't mean everyone should be forced to use them.

Some concrete complaints:

1. Taking an iterator pair does not enforce that the passed iterators are iterators for the exactly same container, which can yeld UB or other subtle bugs. So this is particularly weak, judging just from the static-typing freak as me.

2. There exist structures that allow being iterated only once (streams) and there exist algorithms that require iterating more than once (sorting). Of course the whole design does not make any explicit support for that at the type-system level. There is no distinction between general iterables and iterables-once. Which means you have to document it in the comments.

3. Generally STL feels like a dynamic language. The support you get from the type-system is really, really weak. E.g. without reading the whole lot of documentation, you wouldn't know what to pass to the given STL method, so the compiler is happy. Most of the requirements are not part of the method signature.

4. It is not possible to write a method that takes a container (or iterator) of any type and produces another container (or iterator) of the same or dependent type, but with different contents, and which allows adding more type mappings later, without modifying the source of the method. E.g. applying a transform to bit set elements that would yield a hash set (e.g. convert every element to a string). But this is more a language-level complaint than STL complaint.

5. Iterators are inherently sequential concept. They don't play well with concurrency and parallelism. If you want to process a collection in parallel, converting it to an "iterator form" (in order to give it to some STL method) to just convert it immediately to something else for parallel execution (what would STL probably do) instead of directly processing a collection is not very fortunate. Well, this is a complaint for the future because C++ doesn't have parallel collections yet.
100% agree with #1
90% agree with #2 - depends on whether you like the idea of duck-typing in C++ with templates
100% agree with #3, see #2
Not sure about #4 - can you explain this more? I have never considered something like this before.
100% agree with #5

Overall I really agree with your stance on iterators in C++. They're cool, but they're not done right (perhaps because they're so much like pointers - in fact they basically are pointers with added abstraction).
Last edited on
I agree with iterator problems too.
However #2 and #3 will be dealt with in C++14 (Concepts)
Also there is proposal for iterator<->index conversion, so iterators might be aware of containers they belong too soon.
We have container taking algorithms overloads to deal with #1 besides other uses.
However #2 and #3 will be dealt with in C++14 (Concepts)

I was about to say.

I'm interested to see how concepts will affect the language in the long run, seeing as generic code will become less generic. We'll probably need some Standard Concepts List here on this site, to help beginners learn which concept to use.
As for #4 I'd like the way how Scala solves it:

 
set.map(_.toString)


Now depending on the original type of the set, you'll get:

* immutable.Set[Int] => imutable.Set[String]
* mutable.Set[Int] => mutable.Set[String]
* TreeSet[Int] => TreeSet[String]
* BitSet => TreeSet[String]

I'm not aware of any other language that can do this, even Haskell.

A very nice thing is that it is achieved by the same, shared map method implementation and you can easily extend it to your own collection types or add more mappings (as long as they are non-ambiguous). This is also very useful when designing your own collection, because just by defining a few very simple methods or classes, you get most of Scala library methods supported by your collection, without even writing those methods (just inherit them from traits).

I think you can do that in C++ with some template metaprogramming, but you're right that it's definitely not a built-in language feature in languages I know. As for Mutable Set<Int> -> Mutable Set<String>, if you change one does it change the other or is it like a copy?
In this example it is like a copy - it builds a new collection. If it wasn't, it would be an easy solution to just make the method modify the passed object and return a reference to it, but it is not always desired, especially if you do want to change the type of the object.

I'm not saying you can't do it in C++, but just that you don't get it out of the box, which is pretty neat, especially for beginners. It just works and there are plenty of ready to use methods on collections.

Oh, and another nice example. Can you do that with STL?

1
2
3
List(1,2,3,4) is inferenced as List[Int]
List("a", "b") is inferenced as List[String]
List("a", 1) is inferenced as List[Any]



Note - this is not an overload for each case nor a special compiler magic - there is just one definition of the List constructor and you can do that with your own classes.


Last edited on
Yes everyone is using it now
Yes everyone is using it now

I've not learned any C++11 yet. So, no, not everyone is using it.
I have..in my book it has a sign beside it saying c++11 like long long is in c++11
long long was in C++ before C++11 was even released. It is just some compilers only supported them as extensions, C++11 just made them part of the standard so all compilers use it now.
C++11 just made them part of the standard so all compilers use it now.

That describes almost everything that's new in C++11, not just long long
No becuase I didn't find it useful at all.
@BHX oh but it has a c++11 in my book
Fredbill30 wrote:
No becuase I didn't find it useful at all.
Have you even looked at any of the new features yet?

BHXSpecter wrote:
I've not learned any C++11 yet.
What are you waiting for?
Pages: 1... 5678