In practice, the difference is in the location where the preprocessor searches for the included file.
For #include <filename>
the preprocessor searches in an implementation dependent manner, normally in search directories pre-designated by the compiler/IDE. This method is normally used to include standard library header files.
For #include "filename"
the preprocessor searches first in the same directory as the file containing the directive, and then follows the search path used for the #include <filename>
form. This method is normally used to include programmer-defined header files.
A more complete description is available in the GCC documentation on search paths.
Setting a bit
Use the bitwise OR operator (|
) to set a bit.
number |= 1UL << n;
That will set the n
th bit of number
. n
should be zero, if you want to set the 1
st bit and so on upto n-1
, if you want to set the n
th bit.
Use 1ULL
if number
is wider than unsigned long
; promotion of 1UL << n
doesn't happen until after evaluating 1UL << n
where it's undefined behaviour to shift by more than the width of a long
. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&
) to clear a bit.
number &= ~(1UL << n);
That will clear the n
th bit of number
. You must invert the bit string with the bitwise NOT operator (~
), then AND it.
Toggling a bit
The XOR operator (^
) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the n
th bit of number
.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the n
th bit of number
into the variable bit
.
Changing the nth bit to x
Setting the n
th bit to either 1
or 0
can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n
will be set if x
is 1
, and cleared if x
is 0
. If x
has some other value, you get garbage. x = !!x
will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1
has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n))
will clear the n
th bit and (x << n)
will set the n
th bit to x
.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
Best Answer
If you have a C++11 compiler, I would suggest using a range-based for-loop (see below); or else use an iterator. But you have several options, all of which I will explain in what follows.
range-based for-loop (C++11)
In C++11 (and later) you can use the new range-based for-loop, which looks like this:
The type
char
in the for-loop statement should be the type of the elements of the vectorpath
and not an integer indexing type. In other words, sincepath
is of typestd::vector<char>
, the type that should appear in the range-based for-loop ischar
. However, you will likely often see the explicit type replaced with theauto
placeholder type:Regardless of whether you use the explicit type or the
auto
keyword, the objecti
has a value that is a copy of the actual item in thepath
object. Thus, all changes toi
in the loop are not preserved inpath
itself:If you would like to proscribe being able to change this copied value of
i
in the for-loop as well, you can force the type ofi
to beconst char
like this:If you would like to modify the items in
path
so that those changes persist inpath
outside of the for-loop, then you can use a reference like so:and even if you don't want to modify
path
, if the copying of objects is expensive you should use a const reference instead of copying by value:iterators
Before C++11 the canonical solution would have been to use an iterator, and that is still perfectly acceptable. They are used as follows:
If you want to modify the vector's contents in the for-loop, then use
iterator
rather thanconst_iterator
.supplement: typedef / type alias (C++11) / auto (C++11)
This is not another solution, but a supplement to the above
iterator
solution. If you are using the C++11 standard (or later), then you can use theauto
keyword to help the readability:Here the type of
i
will be non-const (i.e., the compiler will usestd::vector<char>::iterator
as the type ofi
). This is because we called thebegin
method, so the compiler deduced the type fori
from that. If we call thecbegin
method instead ("c" for const), theni
will be astd::vector<char>::const_iterator
:If you're not comfortable with the compiler deducing types, then in C++11 you can use a type alias to avoid having to type the vector out all the time (a good habit to get into):
If you do not have access to a C++11 compiler (or don't like the type alias syntax for whatever reason), then you can use the more traditional
typedef
:side note:
At this point, you may or may not have come across iterators before, and you may or may not have heard that iterators are what you are "supposed" to use, and may be wondering why. The answer is not easy to appreciate, but, in brief, the idea is that iterators are an abstraction that shield you from the details of the operation.
It is convenient to have an object (the iterator) that does the operation you want (like sequential access) rather than you writing the details yourself (the "details" being the code that does the actual accessing of the elements of the vector). You should notice that in the for-loop you are only ever asking the iterator to return you a value (
*i
, wherei
is the iterator) -- you are never interacting withpath
directly itself. The logic goes like this: you create an iterator and give it the object you want to loop over (iterator i = path.begin()
), and then all you do is ask the iterator to get the next value for you (*i
); you never had to worry exactly how the iterator did that -- that's its business, not yours.OK, but what's the point? Well, imagine if getting a value wasn't simple. What if it involves a bit of work? You don't need to worry, because the iterator has handled that for you -- it sorts out the details, all you need to do is ask it for a value. Additionally, what if you change the container from
std::vector
to something else? In theory, your code doesn't change even if the details of how accessing elements in the new container do: remember, the iterator sorts all the details out for you behind the scenes, so you don't need to change your code at all -- you just ask the iterator for the next value in the container, same as before.So, whilst this may seem like confusing overkill for looping through a vector, there are good reasons behind the concept of iterators and so you might as well get used to using them.
indexing
You can also use a integer type to index through the elements of the vector in the for-loop explicitly:
If you are going to do this, it's better to use the container's member types, if they are available and appropriate.
std::vector
has a member type calledsize_type
for this job: it is the type returned by thesize
method.Why not use this in preference to the
iterator
solution? For simple cases, you can do that, but using aniterator
brings several advantages, which I have briefly outlined above. As such, my advice would be to avoid this method unless you have good reasons for it.std::copy (C++11)
See Joshua's answer. You can use the STL algorithm
std::copy
to copy the vector contents onto the output stream. I don't have anything to add, except to say that I don't use this method; but there's no good reason for that besides habit.std::ranges::copy (C++20)
For completeness, C++20 introduced ranges, which can act on the whole range of a
std::vector
, so no need forbegin
andend
:Unless you have a recent compiler (on GCC apparently at least version 10.1), likely you will not have ranges support even if you might have some C++20 features available.
overload std::ostream::operator<<
See also Chris's answer below. This is more a complement to the other answers since you will still need to implement one of the solutions above in the overloading, but the benefit is much cleaner code. This is how you could use the
std::ranges::copy
solution above:Now you can pass your
Path
objects to your output stream just like fundamental types. Using any of the other solutions above should also be equally straightforward.conclusion
Any of the solutions presented here will work. It's up to you (and context or your coding standards) on which one is the "best". Anything more detailed than this is probably best left for another question where the pros/cons can be properly evaluated, but as always user preference will always play a part: none of the solutions presented are objectively wrong, but some will look nicer to each coder.
addendum
This is an expanded solution of an earlier one I posted. Since that post kept getting attention, I decided to expand on it and refer to the other excellent solutions posted here, at least those that I have personally used in the past at least once. I would, however, encourage the reader to look at the answers below because there are probably good suggestions that I have forgotten, or do not know, about.