1

Here are a demo code from C++ primer plus about using using-directive and using-declaration across header files and cpp files, I've made some modification to remove the using declarations in other function to have cout and end and the code errored:

  • namesp.h
#include <string>
#include <iostream>

namespace pers
{
    struct Person
    {
        std::string fname;
        std::string lname;
    };
    void getPerson(Person &);
    void showPerson(const Person &);
};

namespace debts
{
    using namespace pers;

    struct Debt
    {
        Person name;
        double amount;
    };
    void getDebt(Debt &);
    void showDebt(const Debt &);
    double sumDebts(const Debt[], int);
}

  • namesp.cpp
#include "namesp.h"

namespace pers
{
    using std::cin;
    using std::cout;
    using std::endl;

    void getPerson(Person &p)
    {
        cout << "Enter first name: ";
        cin >> p.fname;
        cout << "Enter last name: ";
        cin >> p.lname;
    }

    void showPerson(const Person &p)
    {
        cout << p.lname << ", " << p.fname;
    }
};

namespace debts
{
    void getDebt(Debt &b)
    {
        getPerson(b.name);
        cout << "Enter debt: ";
        cin >> b.amount;
    }

    void showDebt(const Debt &b)
    {
        showPerson(b.name);
        cout << ": $" << b.amount << endl;
    }

    double sumDebts(const Debt bs[], int n)
    {
        double sum;
        for (int i = 0; i < n; ++i)
        {
            sum += bs[i].amount;
        }
        return sum;
    }
}
  • namessp.cpp
#include <iostream>
#include "namesp.h"

void other(void);

int main(void)
{
    other();
    return 0;
}

void other(void)
{
    using namespace debts;
    // using namespace pers;
    // using std::cout;
    // using std::endl;
    Person dg = {"Doodles", "Glister"};
    showPerson(dg);
    cout << endl;    // ERROR: cout and endl was complained no declaration in the scope
    Debt zippy[3] = {{{"Alice", "Jane"}, 100.10}, {{"Bob", "Marley"}, 90.10}, {{"Sam", "Peters"}, 80.10}};
    int i;
    for (i = 0; i < 3; ++i)
    {
        showDebt(zippy[i]);
    }
    cout << "Total debt: $" << sumDebts(zippy, 3) << endl;
    return;
}

  • error:
$ g++ namesp.cpp namessp.cpp                                                                                                                                                                                                                                                      1 ↵
namessp.cpp: In function ‘void other()’:
namessp.cpp:20:5: error: ‘cout’ was not declared in this scope
     cout << endl;
     ^~~~
namessp.cpp:20:5: note: suggested alternative:
In file included from namessp.cpp:1:0:
/usr/include/c++/7/iostream:61:18: note:   ‘std::cout’
   extern ostream cout;  /// Linked to standard output
                  ^~~~
namessp.cpp:20:13: error: ‘endl’ was not declared in this scope
     cout << endl;
             ^~~~
namessp.cpp:20:13: note: suggested alternative:
In file included from /usr/include/c++/7/iostream:39:0,
                 from namessp.cpp:1:
/usr/include/c++/7/ostream:590:5: note:   ‘std::endl’
     endl(basic_ostream<_CharT, _Traits>& __os)
     ^~~~

Based on my understading, function another uses a using directive using namespace debts, since using directive is transitive, it implicitly calls using namespace pers. But why cout and endl(viable through using declarations in namespace pers) are not visible in function another?

lyu.l
  • 282
  • 3
  • 8
  • Please add comments on the lines in the shown code where you get the errors. – Some programmer dude Oct 24 '21 at 07:46
  • 3
    As a probable hint about your problem, you need to learn about the concept of [*translation units*](https://en.wikipedia.org/wiki/Translation_unit_(programming)). The compiler will deal *only* with translation units (basically a single source file with all included header files). As such when the compiler is working on `namessp.cpp` it will not know anything that happened in the `namesp.cpp` source file. That include the `using` statements in the `pers` namespace. – Some programmer dude Oct 24 '21 at 07:50
  • 1
    On another and unrelated note, please try to give your source file names that are semantically relevant. It's very hard to distinguish between `namesp.cpp` and `namessp.cpp` when seeing only the names. – Some programmer dude Oct 24 '21 at 07:51
  • Hi, thanks for the hint, I've added a comment to the line that caused the error. – lyu.l Oct 24 '21 at 07:53
  • 1
    Thanks for the hint of `translation unit`, if I'm understanding this right, the problem occurs in the preprocessing stage of `namessp.cpp`(one `translation unit`), which basically replaces the `namesp.h` with its content. But in `namesp.h`, namespace `pers` doesn't have those using declarations that nominate `cout` and `endl`(those using declarations are in the `pers` namespace extension in `namesp.cpp`(another `translation unit`)), so those variables are not visible in function `other` as a result. – lyu.l Oct 24 '21 at 08:07

0 Answers0