我们是否需要使用“::”为嵌套类型的成员参数添加前缀?

时间:2013-05-11 01:56:25

标签: c++ class templates nested

例如,如果存在名称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);

1 个答案:

答案 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 foobar。)