在C ++命名空间中声明但在其外部定义的函数是否保留该命名空间中的类型?

时间:2018-10-14 23:25:37

标签: c++ namespaces

在3.3命名空间“ A C ++之旅”中,我提到了Stroustrup的模糊示例。他给出了以下示例:

namespace My_Code {
    class complex { /* ... */ };  // class complex is within My_Code scope

    complex sqrt(complex); //takes our locally-defined complex as an argument

    int main(); 
}

// Defining My_Code main function *outside* of the My_Code namespace,
// but this is fine
int My_Code::main() {
    complex z {1, 2};   // My_Code::complex, or std::complex?
    auto z2 = sqrt(z);  // My_Code::sqrt(), or std::sqrt()?
    std::cout << '{' << z2.real() << ',' << z2.imag() << "}\n";
    // ...
}

int main() {
    return My_Code::main();
}

我的问题是:尝试过这种情况,发现期望的类型来自My_Code,为什么,在这种情况下,z和z2的类型属于My_Code吗?当然,如果我们在名称空间之外定义此函数,那么我们将不再使用没有限定条件的我们自己的类型,应该对它们进行限定条件吗?还是我们从特定名称空间实现函数的事实可以解释这种现象?

2 个答案:

答案 0 :(得分:2)

这是为了保持一致性。考虑:

namespace N
{
    struct S
    {
         int f();
    private:
         int g();
         int x;
    };
    int h(int);

    int S::f()
    {
        // member of N::S, therefore not only finds N::S::g() during lookup
        // but has access to private member
        g();
    }
}

int N::S::g()
{
    // member of N::S, therefore finds and has access to N::S::x
    // wouldn't it be weird if it could access members of the class but
    // not its enclosing namespace?
    // therefore it also can lookup N::h()
    return h(x);
}

int N::h(int a)
{
    // member of N, therefore can lookup N::S
    //        just like N::S::g() can find N::h()
    S s;
    return a;
}

成员函数的类外定义可以在类和封闭范围内进行查找,如果对于名称空间成员而言不是相同的,那么您将遇到一个非常奇怪的情况,即名称空间成员对函数可见在外部定义的名称空间取决于它们是否是类成员函数。那真是令人困惑。

答案 1 :(得分:2)

Igor Tandetnik之所以这样说,是因为该标准是这样说的。对于My_Code::至右括号之间的所有内容,名称查找均始于My_Code。

int My_Code::main()定义您的函数main的类型为int并且位于名称空间My_Code中。这意味着My_Code中的功能可以使用。因此,类型zz2属于My_Code。