例如,如果存在名称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);
:
nest1<W> x; bar(x);
:http://ideone.com/3ZuH2Z 答案 0 :(得分:0)
在成员函数名称之后使用的每个名称也会在其类的词法范围内查找。这会导致以下(看似)不一致的行为,因为正常的返回类型在类的词法范围内不:
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
:
如果成员函数的定义在词法定义之外是词法定义,则成员函数名称应使用
::
运算符通过其类名限定。 [注意: 成员函数定义中使用的名称(即,在 parameter-declaration-clause 中包含默认参数(8.3)。 6)或在成员函数体中)按照3.4中的描述查找。 -end note ] [...]
然后在§3.4.1 [basic.lookup.unqual] p8
(非限定名称查找,例如没有::
):
在函数的 declarator-id 31 X 的成员函数(9.3)的定义中使用的名称> [......]应以下列方式之一宣布:
- [...]
- 应该是类
X
的成员,或者是X
(10.2)的基类成员,或者- [...]
(我的示例中的 declarator-ids 是foo
和bar
。)