为什么我需要在返回函数类型之前添加名称空间前缀? 我正在编写一些C++代码。在这些代码中,有嵌套的名称空间,如A::B::C。A、B、C是名称空间。我在a中定义类型a,然后在B中重新定义类型a。根据我的理解,a::B::TYPEA将屏蔽a::TYPEA。但为什么我仍然在函数的返回类型中添加名称空间前缀A::B::TYPEA namespace A { typedef int TYPEA; namespace B { class ClassB { public: typedef int TYPEA; TYPEA foo(); }; ClassB::TYPEA ClassB::foo() { // ... } } }
根据我的理解,A::B::ClassB::TYPEA将屏蔽A::TYPEA,为什么我不能这样定义foo:为什么我需要在返回函数类型之前添加名称空间前缀? 我正在编写一些C++代码。在这些代码中,有嵌套的名称空间,如A::B::C。A、B、C是名称空间。我在a中定义类型a,然后在B中重新定义类型a。根据我的理解,a::B::TYPEA将屏蔽a::TYPEA。但为什么我仍然在函数的返回类型中添加名称空间前缀A::B::TYPEA namespace A { typedef int TYPEA; namespace B { class ClassB { public: typedef int TYPEA; TYPEA foo(); }; ClassB::TYPEA ClassB::foo() { // ... } } },c++,C++,根据我的理解,A::B::ClassB::TYPEA将屏蔽A::TYPEA,为什么我不能这样定义foo: TYPEA ClassB::foo() { // ... } TYPEA ClassB::foo() { // ... } 这只是C++名称查找的一个规则。函数的前导返回类型不在该函数的范围内,因此在该上下文中,编译器不会在ClassB范围内搜索名称TYPEA ClassB::TYPEA ClassB::foo() {} // resolves to // int C
TYPEA ClassB::foo()
{
// ...
}
TYPEA ClassB::foo()
{
// ...
}
这只是C++名称查找的一个规则。函数的前导返回类型不在该函数的范围内,因此在该上下文中,编译器不会在
ClassB
范围内搜索名称TYPEA
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
但是,尾随返回类型在函数的范围内,因此如果使用尾随返回,则将在ClassB
的范围内找到TYPEA
:
auto ClassB::foo() -> TYPEA
{
// ...
}
这只是C++名字查找的一个规则。函数的前导返回类型不在该函数的范围内,因此在该上下文中,编译器不会在
ClassB
范围内搜索名称TYPEA
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
但是,尾随返回类型在函数的范围内,因此如果使用尾随返回,则将在ClassB
的范围内找到TYPEA
:
auto ClassB::foo() -> TYPEA
{
// ...
}
由于作用域的限制,
TYPEA
被认为是A::B::ClassB::TYPEA
在类声明和方法定义中的任何地方,以及A::TYPEA
在命名空间A
中的其他地方
namespace A
{
typedef int TYPEA;
namespace B
{
/*
TYPEA refers to A::TYPEA
*/
class ClassB
{
public:
typedef int TYPEA;
TYPEA foo();
/*
TYPEA refers to A::B::ClassB::TYPEA
*/
};
/*
TYPEA refers to A::TYPEA
*/
ClassB::TYPEA ClassB::foo()
{
// ...
/*
TYPEA refers to A::B::ClassB::TYPEA
*/
}
};
/*
TYPEA refers to A::TYPEA
*/
}
}
根据我的理解,A::B::ClassB::TYPEA将屏蔽A::TYPEA,为什么我不能这样定义foo:
TYPEA ClassB::foo()
{
// ...
}
TYPEA ClassB::foo()
{
// ...
}
实际上,对于你的特殊情况,你可以。由于两个TYPEA
都被类型定义为int
,因此无论您是否在返回类型前面加上ClassB
,代码都会进行编译
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
这两个签名是一样的。现在,如果类型不同,那么签名将无法解析,您将得到一个编译错误。例如:
namespace A
{
typedef double TYPEA; // double
namespace B
{
class ClassB
{
public:
typedef int TYPEA; // int
TYPEA foo();
};
ClassB::TYPEA ClassB::foo() // not the same as `TYPEA ClassB::foo()` !!!
{
// ...
}
}
}
这里,需要名称空间前缀来消除
TYPEA
的歧义,并指定ClassB
下由于作用域而定义的类型,TYPEA
被认为是A::B::ClassB::TYPEA
在类声明和方法定义中的任何地方,以及A::TYPEA
在命名空间A
中的任何地方
namespace A
{
typedef int TYPEA;
namespace B
{
/*
TYPEA refers to A::TYPEA
*/
class ClassB
{
public:
typedef int TYPEA;
TYPEA foo();
/*
TYPEA refers to A::B::ClassB::TYPEA
*/
};
/*
TYPEA refers to A::TYPEA
*/
ClassB::TYPEA ClassB::foo()
{
// ...
/*
TYPEA refers to A::B::ClassB::TYPEA
*/
}
};
/*
TYPEA refers to A::TYPEA
*/
}
}
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
根据我的理解,A::B::ClassB::TYPEA将屏蔽A::TYPEA,为什么我不能这样定义foo:
TYPEA ClassB::foo()
{
// ...
}
TYPEA ClassB::foo()
{
// ...
}
实际上,对于你的特殊情况,你可以。由于两个TYPEA
都被类型定义为int
,因此无论您是否在返回类型前面加上ClassB
,代码都会进行编译
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
这两个签名是一样的。现在,如果类型不同,那么签名将无法解析,您将得到一个编译错误。例如:
namespace A
{
typedef double TYPEA; // double
namespace B
{
class ClassB
{
public:
typedef int TYPEA; // int
TYPEA foo();
};
ClassB::TYPEA ClassB::foo() // not the same as `TYPEA ClassB::foo()` !!!
{
// ...
}
}
}
这里,需要使用名称空间前缀来消除TYPEA
的歧义,并指定ClassB
下定义的类型,您所说的“屏蔽”是什么意思?你想在这里干什么?想写一个更有意义的例子吗?你说的“盾”是什么意思?你想在这里干什么?想写一个更有意义的例子吗?
ClassB::TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}
----
TYPEA ClassB::foo() {}
// resolves to
// int ClassB::foo() {}