Thomas1965 wrote: |
---|
Can you show me an example where the compiler isn't able to warn you? |
|
|
|
|
std::distance
was being called, and there was no compilation error or warning. They didn't find out until they asked the question.std::copy
specifies that one wants the std version, not boost::copy
, or some other copy from somewhere.namespace
- then you get a compilation error: in this case the technical blunder JLBorges mentioned.
|
|
std::cout << me::distance(ii, jj) << " ";
using std::cout;
That is fine, but it gets tiresome: it's easy to accumulate 20 of those, especially if using algorithms.std::
std::
before each std thing is the best practise, and that is why experts and many others do exactly that, all the time :+) And my intention of bringing this up in the first place was to encourage good practise, even if it was my 2 cents worth. using namespace std;
was the main thing.
|
|
using namespace std;
is to point people in the general direction of writing code like you do :+)std::cout << quoted( accumulate( seq, cat ) ) << '\n' ;
for
, which seems to be able to deduce begin
and end
. I understand the flexibility that comes from being able to specify various iterators (const, reverse etc., and for partial sequences), but could this be an additional overload ?
|
|
In short: You can and should use namespace using declarations and directives liberally in your implementation files after #include directives and feel good about it. Despite repeated assertions to the contrary, namespace using declarations and directives are not evil and they do not defeat the purpose of namespaces. Rather, they are what make namespaces usable. ... But using declarations and directives are for your coding convenience, and you shouldn't use them in a way that affects someone else's code. In particular, don't write them anywhere they could be followed by someone else's code: Specifically, don't write them in header files (which are meant to be included in an unbounded number of implementation files, and you shouldn't mess with the meaning of that other code) or before an #include (you really don't want to mess with the meaning of code in someone else's header). - Sutter and Alexandrescu in 'C++ Coding Standards: 101 Rules, Guidelines, and Best Practices' |
SF.6: Use using namespace directives ... for foundation libraries (such as std) ... using namespace can lead to name clashes, so it should be used sparingly. However, it is not always possible to qualify every name from a namespace in user code (e.g., during transition) and sometimes a namespace is so fundamental and prevalent in a code base, that consistent qualification would be verbose and distracting. CoreGuideLines https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rs-using |
A range is an object that refers to a sequence of elements, conceptually similar to a pair of iterators. One prime motivation for ranges is to give users a simpler syntax for calling algorithms. Rather than this:
Ranges would give us a pithier syntax: std::sort( v ); Allowing algorithms to take a single range object instead of separate begin and end iterators brings other benefits besides convenience. In particular: It eliminates the possibility of mismatched iterators. It opens the door to range adaptors which lazily transform or filter their underlying sequence in interesting ways. Range adaptors are far more compelling than iterator adaptors due to the fact that only a single object, the range object, needs to be adapted; hence, adaptors can be easily chained to create lazy computational pipelines, as in the code below which sums the first 10 squares:
... From the perspective of the standard library, a range is a pair of iterators. But there are other interesting ways to denote a range of elements: An iterator and a count of elements An iterator and a (possibly statefull) predicate that indicates when the range is exhausted. One of these three range types can be used to denote all other range types, like an iterator and a sentinel value (e.g. a null-terminated string), or a range that spans disjoint ranges. Ideally, we would like our Range abstraction to be general enough to accommodate the three different kinds of ranges since that would increase the applicability of the algorithms. |