例如,考虑以下名称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
:然后在
§3.4.1 [basic.lookup.unqual] p8
(不合格的名称查找,例如,不使用::
):(在我的示例中,声明者ID是
foo
和bar
。)