例如,考虑以下名称冲突的地方 nest1
:
template <typename U> class nest1 {};
class cls {
public:
template <typename V> class nest1 {};
template <typename W> class nest2 {
public:
void bar(nest1<W> x);
};
};
template <typename W>
void cls::nest2<W>::bar(nest1<W> x) {} // how does compiler know which nest<1>?
- 编译器如何知道
bar
是否存在?需要nest1<W>
或cls::nest1<W>
如果我们不使用cls::
作为前缀(例如bar(cls::nest1<W> x)
)? - 显式前缀
cls::
是好习惯吗?无论如何?
注意:编译器实际上选择隐式声明 bar(cls::nest1<W> x)
:
- 调用
cls::nest1<W> x; bar(x);
作品:http://ideone.com/3ZuH2Z - 路过
nest1<W> x; bar(x);
失败:http://ideone.com/6HmA3f
最佳答案
在成员函数名称之后使用的每个名称也在其类的词法范围内查找。这会导致以下(看似)不一致的行为,因为正常的返回类型不在类的词法范围内:
struct X{
struct Y{};
Y foo(Y);
Y bar(Y);
};
// normal return type is before 'foo', needs explicit scope qualification
// parameter doesn't (after 'foo')
X::Y X::foo(Y y){ return y; }
// trailing-return-type also doesn't (after 'bar')
auto X::bar(Y y) -> Y{ return y; }
关于这方面的标准,我们看§9.3 [class.mfct] p5
:
If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the
::
operator. [ Note: A name used in a member function definition (that is, in the parameter-declaration-clause including the default arguments (8.3.6) or in the member function body) is looked up as described in 3.4. —end note ] [...]
然后在 §3.4.1 [basic.lookup.unqual] p8
(非限定名称查找,例如没有 ::
):
A name used in the definition of a member function (9.3) of class
X
following the function’s declarator-id31 [...] shall be declared in one of the following ways:
- [...]
- shall be a member of class
X
or be a member of a base class ofX
(10.2), or- [...]
(在我的示例中,declarator-ids 是 foo
和 bar
。)
关于c++ - 我们是否需要在嵌套类型的成员参数前加上 "::"前缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16493015/