是否在C++命名空间中声明的函数,但在其外部定义的函数将从该命名空间保留类型?
我指的是Stroustrup在3.3名称空间中的“C++之旅”的一个稍微模糊的例子。他举了以下例子:是否在C++命名空间中声明的函数,但在其外部定义的函数将从该命名空间保留类型?,c++,namespaces,C++,Namespaces,我指的是Stroustrup在3.3名称空间中的“C++之旅”的一个稍微模糊的例子。他举了以下例子: 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(); } // D
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();
}
我的问题是:尝试了这一点,发现预期的类型来自我的_代码,为什么在这种情况下z和z2的类型属于我的_代码?当然,如果我们在名称空间之外定义这个函数,那么我们就不再在没有限定的情况下使用我们自己的类型,我们应该限定它们吗?或者,我们从特定名称空间实现函数的事实是否解释了这种行为?这是为了一致性。考虑:
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;
}
成员函数的类外定义可以在类和封闭作用域中进行查找,如果命名空间成员的查找不正确,则会出现一种非常奇怪的情况,即命名空间成员对外部定义的命名空间的函数可见,这取决于它们是否为类成员函数。这真是令人困惑。这是为了一致性。考虑:
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;
}
成员函数的类外定义可以在类和封闭作用域中进行查找,如果命名空间成员的查找不正确,则会出现一种非常奇怪的情况,即命名空间成员对外部定义的命名空间的函数可见,这取决于它们是否为类成员函数。这真的很让人困惑。正如标准所说的那样,因为标准是这么说的。对于My_Code::和右大括号之间的所有内容,名称查找从My_Code开始
int My_Code::main定义函数main的类型为int,并且驻留在名称空间My_Code中。这意味着My_代码中的功能可以使用。因此,类型z和z2属于My_代码。As,因为标准如此规定。对于My_Code::和右大括号之间的所有内容,名称查找从My_Code开始
int My_Code::main定义函数main的类型为int,并且驻留在名称空间My_Code中。这意味着My_代码中的功能可以使用。因此,类型z和z2属于My_代码。查找ADL:因为标准上这么说。对于My_Code::和右大括号之间的所有内容,名称查找从My_Code开始。此外,您不包括任何标准头-为什么您甚至希望声明std::complex。更不用说找到了?@IgorTandetnik我只是引用了书中的例子。在我用来测试的代码中,我包含了复杂的标题。事实证明,这并不是必须的。@Quimby:ADL与此无关。我相信int My_Code::func{bla}与名称空间My_Code{int func{bla}相同,因为标准是这样说的。对于My_Code::和右大括号之间的所有内容,名称查找从My_Code开始。此外,您不包括任何标准头-为什么您甚至希望声明std::complex。更不用说找到了?@IgorTandetnik我只是引用了书中的例子。在我用来测试的代码中,我包含了复杂的标题。事实证明,这不是必须的。@Quimby:ADL与此无关。我相信int My_Code::func{bla}与名称空间My_Code{int func{bla}相同因此,我认为考虑类外定义和更普遍的名称空间外定义的方法是,我们这样做是出于表示与定义分离等原因,但就编译器而言,它们可以访问的范围没有变化?@DanielSoutar:正确。此外,类内定义会自动添加内联关键字,因此类外定义有助于避免这种情况。因此,我认为考虑类外定义和更普遍的命名空间外定义的方法是,我们这样做是出于表示与定义分离等原因,但就编译器而言,他们访问的范围没有变化?@DanielSoutar:正确。此外,类内定义会自动添加inline关键字,因此类外定义有助于避免这种情况。