2013-05-11 58 views
2

例如,请考虑以下那里是名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)

+0

同样,当你有一个全局变量,并与同名的静态数据成员的。 – chris 2013-05-11 01:59:20

+0

因此,它只是剥离图层并在最接近的父/祖类中找到所需的声明? – mchen 2013-05-11 02:13:06

+0

哦,我认为它会选择全球性的。你应该在你的问题中指定。 – chris 2013-05-11 02:17:21

回答

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; } 

对于standardese对于这一点,我们来看看§9.3 [class.mfct] p5

如果成员函数的定义在其词类定义的词汇之外,则应使用::运算符通过其类名称限定成员函数名称。 [注:在一个成员函数定义中使用的名称(即,在包括默认参数(8.3.6参数声明子句)或成员函数体)被查找所描述在3.4。末端音符] [...]

然后在§3.4.1 [basic.lookup.unqual] p8(不合格的名称查找,例如,没有::):

在一个成员函数的定义中使用的名称(9.3 )的类X以下功能的声明符-ID [...]应以下列方式之一进行申报:

  • [...]
  • X类的成员或者是基类的X(10.2)中的一员,或
  • [...]

(该说明符的IDS在我的例子是foobar

相关问题