跨文件和 using 指令的 C++ 命名空间问题

Issues with C++ namespace across file and using directive

提问人:lyu.l 提问时间:10/24/2021 最后编辑:lyu.l 更新时间:10/24/2021 访问量:50

问:

以下是来自 C++ 入门的演示代码以及关于使用和跨头文件和 cpp 文件的演示代码,我做了一些修改以删除函数中的使用声明,并且代码错误:using-directiveusing-declarationothercoutend

  • 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);
}

  • 名称p:.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;
    }
}
  • 名称sp.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;
}

  • 错误:
$ 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)
     ^~~~

根据我的理解,函数使用一个 using 指令,因为 using 指令是可传递的,所以它隐式调用 .但是为什么和(通过在命名空间中使用声明可行)在函数中不可见?anotherusing namespace debtsusing namespace perscoutendlpersanother

C++ using-declaration

评论

0赞 Some programmer dude 10/24/2021
请在显示的代码中出现错误的行上添加注释。
3赞 Some programmer dude 10/24/2021
作为关于您的问题的可能提示,您需要了解翻译单元的概念。编译器将处理翻译单元(基本上是一个包含所有头文件的单个源文件)。因此,当编译器在处理时,它不会知道源文件中发生的任何事情。这包括命名空间中的语句。namessp.cppnamesp.cppusingpers
1赞 Some programmer dude 10/24/2021
在另一个不相关的说明中,请尝试提供语义相关的源文件名。当只看到名字时,很难区分和。namesp.cppnamessp.cpp
0赞 lyu.l 10/24/2021
嗨,感谢您的提示,我在导致错误的行中添加了注释。
1赞 lyu.l 10/24/2021
感谢您的提示,如果我理解正确的话,问题发生在 (one ) 的预处理阶段,它基本上用它的内容替换了 。但是在 中,命名空间中没有那些使用提名和声明的变量(那些使用声明的变量在(另一个)的命名空间扩展中),因此这些变量因此在函数中不可见。translation unitnamessp.cpptranslation unitnamesp.hnamesp.hperscoutendlpersnamesp.cpptranslation unitother

答: 暂无答案