As can be seen from https://stackoverflow.com/a/26614984/481267 the following headers are guaranteed by the standard to #include <initializer_list>:
Everything in [containers]
<utility>
<string>
<algorithm>
<random>
<valarray>
<regex>
Most of these headers declare at least one function that takes a std::initializer_list<E> argument, so it makes sense. However,
<array>, <stack>, and <queue> have no such functions, although perhaps it makes sense to treat all containers uniformly here.
<utility> has no such functions.
<iterator> does have functions with an initializer_list argument (rbegin, rend) but it's not specified to include <initializer_list>.
What is the rationale behind these exceptions?
Seems like there is no explicit rationale, just that some proposals for additions to the standard were made and those proposals were accepted.
At the very end of the document N2672 Initializer List proposed wording it just says:
In 20.2 Utility components [utility] paragraph 1:
This subclause contains some basic function and class templates that are used throughout the rest of the library.
Header <utility> synopsis
#include<initializer_list>
namespace std {
So, the authors of the paper saw initializer_list as a utility, and so it ought to be included with the <utility> header. And therefore it is.
The paper didn't propose any changes to the <iterator> header, so none were made.
Related
#include <iostream>
using namespace std;
int main(){
swap(a[i],a[j])
}
In this the swap function work automatically or I need to create a another swap function to solve this?
swap is not a keyword in C++ but rather a function from the C++ standard library. So to use it you need to bring in the function from the appropriate C++ standard library header. Unfortunately std::swap has been rather itinerant since it first made it into the C++ standard:
Up to but not including C++11, you need to #include <algorithm>
From C++11 you need to #include <utility>
From C++17 you can #include <string_view> instead
Relying on the implicit inclusion of the header means you're not writing portable C++.
I came across an expression that states: vector<int> pair(n). As pair is an inbuilt structure in itself, can we use it as a variable name in c++ and why??
As pair is an inbuilt structure in itself, can we use it as a variable name in c++ and why?
That is not correct. The Standard Template Library provides a class template called "pair" but that is not an inbuilt type and, furthermore, "pair" is neither a keyword nor a reserved word in the C++ language.
Furthermore, the aforementioned "pair" template is actually provided (in the <utility> header) in the std namespace, so its fully qualified name is std::pair. So, unless you both #include <utility> (explicitly or implicitly) and are using std::pair; (or using namespace std; – but see here), you can use the name, "pair," as an identifier, just like any other non-reserved word.
In fact, even if you do #include <utility> and are using std::pair; (or using namespace std;), you can still use "pair" as an identifier, as mentioned the comment by chris.
Yes, you can. The templates from the standard library are called std::pair and std::vector. They are not built-in, in the sense that they aren't part of the language, but part of the standard library. Hence this is not a problem:
#include <vector>
std::vector<int> pair(n);
One can use using directives to drop the std:: prefix:
#include <vector>
using std::vector;
vector<int> pair(n);
Commonly used is also using namespace std;:
#include <vector>
using namespace std;
vector<int> pair(n);
Though, once you pulled the complete namespace into scope, the code can be rather confusing.
Read Why is “using namespace std;” considered bad practice? and try to avoid it. And give proper names. std::pair is rather common, so you better choose a better name for the vector, it certainly is not a pair.
std::pair is not an "in-built structure". It's a qualified name from the Standard Library. Since it's qualified, it generally does not clash with your own names.
This is exactly why namespaces were added to the C++ language.
I am working with Visual Studio 2017 Community Edition. It allows me to use both size_t and std::size_t without the appropriate includes. It appears to work with most of the std library. I assume it is because parts of the library itself use it. For instance one example that I found led to this behave was with vector.
#include <vector>
#include <iostream>
int main()
{
size_t a = 42;
std::size_t b = 0;
std::cout << a << b;
std::cin.ignore();
}
Presumably this is because the size() function returns an std::size_t. Is this just a header dependency and I can avoid it with the proper include? That still doesn't explain why I can call it with the namespace scope.
(I'm not using using namespace std.)
This question implies that not all headers in the std library should have the definition.
Strictly speaking your code is illegal. The size_t type is required to be declared in the following headers:
<cstddef>
<cstdio>
<cstdlib>
<cstring>
<ctime>
<cwchar>
But also the standard allows standard headers to include other standard headers. So most likely the header <vector> in the standard library used by MSVC includes one of the headers above. This is allowed, but not mandated by the standard so this will work on your setup, but can fail to work on other standard library implementations, even on a future version of the same one you are using.
So in conclusion try to include all the headers required by the standard for all the definitions you are using.
IMHO this is a faulty behavior, but is the required price C++ pays for backward compatibility to the inclusion system that seemed a reasonable design many years ago. The limitations and drawbacks of this are well known today and so the committee is working on modules, which is a modern alternative to the current inclusion mechanism.
As to why you can use size_t without std:::
<cstddef> is required to declare std::size_t and may also optionally declare (or bring in the declaration of) size_t in the global scope.
<stddef.h> is a C backward compatible header and it declares size_t at the global scope.
So either <cstddef> declares size_t at a global level and is included by <vector> or <stddef.h> is included by <vector> - most likely indirectly via <cstddef>.
https://stackoverflow.com/a/283023/2805305
In the code below I create an insert_iterator without including the iterator header.
How is possible that this compiles? I'm new to c/c++ so this will likely have an obious explanation.
#include <list>
//#include <iterator>
int main()
{
std::list<int> mylist(10,1);
std::insert_iterator<std::list<int> > it(mylist,mylist.begin());
return(0);
}
It happens to compile because some of the other headers, <list> in your case, is pulling <iterator> as well. This may work fine with one implementation but fail on a different one, or even on the next version of your current library implementation.
You should always include the headers that define the stuff you use, to make sure it will compile everywhere. Note that there are some guarantees of standard headers that are pulled by other standard headers, but I don't think this is one of those exceptions.
The swap function template was moved from <algorithm> to <utility> in C++0x. Does the former include the latter in C++0x? Or do they both include a common header the defines swap?
In other words, is the following code guaranteed to compile in C++0x?
#include <algorithm> // will this pull in std::swap?
// ...
using std::swap;
swap(a, b);
The FDIS (n3290), in Annex C, "Compatibility", C.2.7 says:
17.6.3.2
Effect on original feature: Function swap moved to a different
header
Rationale: Remove dependency on <algorithm> for swap.
Effect on
original feature: Valid C++ 2003 code that has been compiled expecting
swap to be in <algorithm> may have to instead include <utility>.
So no, it's not guaranteed to compile, this is intentionally a breaking change. Whether individual implementations will actually break C++03 code is another matter. As you point out it's easy enough for them not to, by defining swap via either header. But there's a choice between making it easier to port C++03 code to C++0x, vs. helping people write strictly conforming C++0x.