从iso C ++ n3290开始:依赖于参数的名称查找:

时间:2011-07-28 09:39:20

标签: c++ namespaces c++11 name-lookup

来自iso C ++ n3290:依赖于参数的名称查找:第3.4.2节,第4段

When considering an associated namespace, the lookup is the same as the lookup
performed when the associated namespace is used as a qualifier (3.4.3.2) except
 that:
 — Any using-directives in the associated namespace are ignored.
 — Any namespace-scope friend functions or **friend function templates** declared
   in associated classes are visible within their respective namespaces even if 
   they are not visible during an ordinary lookup (11.3).
 — All names except those of(possibly overloaded) functions and function 
    templates are ignored.

这里与2003年早些时候的标准相比,他增加了第3分。 可以任何人解释它是如何可能的......用一个例子expalin ....(重载)..

Andalso他说,在第二点,他包括朋友的功能模板(我知道noraml calss朋友的功能)..任何人都可以解释这就是显示那种声音。

1 个答案:

答案 0 :(得分:2)

我认为查找应该总是这样,并且更多的是澄清而不是实际的更改。我不确定它是否被添加是因为在其他地方添加了一些其他措辞需要更清楚,编译器在某些极端情况下实际上有所不同,或者某些机构质疑什么是正确的实现。

广告点2.就像你可以声明函数f是c类的朋友一样,你也可以声明函数模板t是c类的朋友。声明是不同的,因为它明确提到了模板参数,所以他们认为需要明确两种情况都适用。

template <typename T> bool f(T);
class c {
    friend bool f<c>(c); // only particular instantiation is friend
    template <typename T> friend bool f<T>(T); // all instantiations are friends
}

(当然,你可以将它与c作为模板本身结合起来,以获得无限的乐趣。)

广告点3.该子句意味着如果在包含类f的命名空间n中查找函数f,则不考虑类f(如果您编写n :: f,则需要该类)。 “可能超负荷”并不一定存在。函数总是可以重载,所有命名空间中发现的所有重载都将包含在最终的重载决策中。

namespace n {
    class c { ... };
    class e { ... } f;
}

namespace o {
    class d { ... };
    void f(c &, d &) { ... };
    void f(c &, d &, bool) { ... };
}

namespace p {
    f(c(), d());
}

f(c(), d())的关联命名空间同时为no。但是n::f不是一个函数,而是一个(可能是函子)实例,因此不予考虑(虽然旧的措辞允许考虑f的{​​{1}})。 operator()被重载,所有重载都被考虑(并且在收集了f的所有可能含义之后,排除了3参数变量,因为只给出了2个参数)。