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?

5
  • Please add comments on the lines in the shown code where you get the errors. Commented Oct 24, 2021 at 7:46
  • 3
    As a probable hint about your problem, you need to learn about the concept of translation units. 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. Commented Oct 24, 2021 at 7: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. Commented Oct 24, 2021 at 7:51
  • Hi, thanks for the hint, I've added a comment to the line that caused the error. Commented Oct 24, 2021 at 7: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. Commented Oct 24, 2021 at 8:07

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.