例如,考虑以下名称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是foobar。)

    10-06 13:19