Search code examples
c++stringincludestdusing

Why do you need to use include when you have declared a using?


I'm learning C++ and I got stuck on why this happends. This code will compile and run perfectly, however if I uncomment the //cout << foo << endl; it won't compile.

#include <iostream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{

    string foo = "temporary";

    //cout << foo << endl;

    // Pause then exit
    system("pause");
    return 0;
}

I solved it by adding: #include <string>. Can anybody tell me why this is becuase to me (coming from C#) this doesn't make sense why you are allowed to create a string object but not printing it?

Thanks!


Solution

  • When you #include <iostream>, it's up to the header to include whatever other headers and consequence declarations and definitions it wants - the C++ Standard doesn't forbid it including more than is strictly necessary to provide the required functionality. Clearly, with your compiler/version, #include <iostream> is also including enough of the string related definitions to know there's a template <...> std::basic_string::basic_string(const char*); constructor (std::string is a typedef to a specific instantiation of basic_string for char) such that your code is known valid:

    string foo = "temporary";
    

    Still, when you went to stream foo, it clearly hadn't seen a matching definition ala template <...> std::ostream& operator<<(std::ostream&, const basic_string<...>&) that specifies how streaming is to be performed: that's why the compiler complained. The definition for operator<< is probably in your <string> header, which is why it really is needed before streaming a string.

    You can observe this yourself by asking your compiler to output and not delete preprocessed files, which show the translation unit after #includes have been expanded. You'll find the options to do so somewhere in your project's build configuration.

    All up, that's why you might sometimes have code work with fewer includes than are strictly necessary. If you realise you've done this, it's always a good idea to include the other headers, ensuring portability to other compilers and future versions of the same compiler.