2

Let's say, I declare function_x by

vector<int> function_x(int i1, int i2);

in function.h, and define it by

vector<int> function_x(int i1, int i2) {
    vector<int> vec;
    vec.push_back(i1);
    vec.push_back(i2);
    return vec;
}

in function.cpp.

To use vector, I need to write #include <vector> in function.h.

If so, I don't need to write #include <vector> in function.cpp because I put #include "function.h" anyway and it contains #include <vector>.

But I feel a little weird because I use vector in function.cpp without including <vector> (directly).

Is this a normal way to use <vector> (or any STL container)? Or, should I write #include <vector> in function.cpp for explicitness even if I'm sure it's unnecessary? (<vector> should have include guard)

iceclimber
  • 37
  • 7
  • Set aside the fact that you should use `std::vector` as a return type, this question sounds quite opinion-based to me. – skypjack Oct 31 '16 at 07:20
  • Hmm, I guess there are two way: write `#include ` in header AND source for reliability, or write `#include ` only in header for simplicity? – iceclimber Oct 31 '16 at 07:26
  • @skypjack Yea I definitely use `std::vector` in real code. – iceclimber Oct 31 '16 at 07:28

3 Answers3

3

You should #include <vector> in every file that needs it, headers and sources. There is not always a one to one relationship between headers and sources and you never know how the structure of the program might change over time. Keeping the relationships simple eases maintenance.

For example it can get fairly complex trying to track if an #include file has already been included by one of the headers. And where does it end? Do you only accept includes or do you accept includes of includes?

It is also much harder to tell what the current file depends on if you have to hunt through your includes to try to resolve where all the symbols come from.

Galik
  • 47,303
  • 4
  • 80
  • 117
  • 3
    Disagree: it is not possible to call `function_x` without `vector` having being included already (because the definition would have failed to compile). It keeps the code simpler to avoid redundant include lines. – M.M Oct 31 '16 at 07:14
  • @M.M I personally find it more complex trying to track if an include file has already been included by one of the headers. And where does it end? Do you only accept includes or do you accept includes of includes? It is also much harder to tell what the current file depends on if you have to hunt through your includes to try to resolve where all the symbols come from. – Galik Oct 31 '16 at 07:29
  • Development tools easily list all dependencies; and if the file hasn't been included you'll know it due to compilation failing. I guess it could be a policy in a gigantic codebase that takes half an hour to build or produce a dependency view – M.M Oct 31 '16 at 19:26
2

But I feel a little weird

There is nothing that should make you feel weird. It is absolutely normal to have the library files included in header files. Header files would be included to the .cpp files anyway.

In fact, by including the relevant files in .h, you can be assured that the .h file you are including in .cpp file has all the necessary functionality .

Very well stated here :

Including a header file produces the same results as copying the header file into each source file that needs it. Such copying would be time-consuming and error-prone. With a header file, the related declarations appear in only one place. If they need to be changed, they can be changed in one place, and programs that include the header file will automatically use the new version when next recompiled. The header file eliminates the labor of finding and changing all the copies as well as the risk that a failure to find one copy will result in inconsistencies within a program.

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • But what happens if he decides to return by pointer instead, and realize that he can forward declare std::vector and remove the `#include ` in the header. Now it won't compile. (OK, maybe std::vector is not applicable to forward declaration due to being in namespace std, but you get the point) – simon Oct 31 '16 at 07:19
  • It is not possible to forward declare `std::vector` (in absence of `#include `) without introducing undefined behaviour. – Peter Oct 31 '16 at 12:27
0

It is a fair bet that a function.cpp will #include function.h, since it is probably the simplest possible way to get the compiler to check that the header file and source file don't get out of sync. Most programmers will also expect that function.h will provide declarations needed by ALL source files, including function.cpp, as well as #includeing any other necessary headers. So you are unlikely to confuse many developers by leaving #include <vector> out of function.cpp. That said, if you can't get over feeling "a little weird", it makes little real difference to put it in. But there is little real benefit either.

BTW: specify the return type for your function as std::vector<int> rather than vector<int>. The second relies on a using declaration being in the header file. And such declarations are a bad idea in header files. There are numerous explanations of why this is so, including this link

Community
  • 1
  • 1
Peter
  • 35,646
  • 4
  • 32
  • 74