在继承的成员字段中的成员函数内使用声明

huangapple go评论108阅读模式
英文:

using declaration inside a member function for an inherited member field

问题

在函数内部,可以使用using声明来将一个名称引入当前作用域,例如:

  1. namespace A {
  2. int y;
  3. }
  4. void f() { using A::y; }

using声明可以在类定义中使用,以改变继承成员的可访问性,同时也可以显式地引入来自模板类的继承成员,例如:

  1. template <bool activate>
  2. struct A {
  3. int x;
  4. };
  5. template <bool activate>
  6. struct B : public A<activate> {
  7. using A<activate>::x;
  8. };

这样做特别有用,因为它避免了通过this->xA<activate>::x来访问x的需要。这只能在定义的类体内部使用,而不能在成员函数内部使用,例如:

  1. template <bool activate>
  2. struct A {
  3. int x;
  4. };
  5. template <bool activate>
  6. struct B : public A<activate> {
  7. int f() const noexcept {
  8. // 这将产生错误:&quot;error: using-declaration for member at non-class scope&quot;
  9. // using A<activate>::x;
  10. return x;
  11. }
  12. };

对于语言中这种限制的合理性,即using A<activate>::x只能放在类的定义内部,是否有合理性的解释?

英文:

Inside a function one can employ the using declaration to import a name in the current scope, like

  1. namespace A {
  2. int y;
  3. }
  4. void f() { using A::y; }

A using declaration can be used in a class definition, to alter the accessibility of an inherited member, but also it is useful to explicitly bring a member inherited from a template class

  1. template &lt;bool activate&gt;
  2. struct A {
  3. int x;
  4. };
  5. template &lt;bool activate&gt;
  6. struct B : public A&lt;activate&gt; {
  7. using A&lt;activate&gt;::x;
  8. };

This is particularly useful, as it avoids the need to access to x via this-&gt;x or A&lt;activate&gt;::x. This can be used only inside the body of the definition, but not inside a member function.

  1. template &lt;bool activate&gt;
  2. struct A {
  3. int x;
  4. };
  5. template &lt;bool activate&gt;
  6. struct B : public A&lt;activate&gt; {
  7. int f() const noexcept {
  8. // This gives: &quot;error: using-declaration for member at non-class scope&quot;
  9. // using A&lt;activate&gt;::x;
  10. return x;
  11. }
  12. };

Is there a rationale for this restriction of the language, that is, for the fact that using A&lt;activate&gt;::x can only be placed inside the definition of the class?

答案1

得分: 2

在《C++设计与演化》中没有直接关于此主题的声明,因此很难可靠地推断出这样做的意图。 也就是说,直到最近为止,标准将using-declaration描述为对命名声明的同义词的引入声明。 从这个观点来看,将成员声明归属于块作用域会显得有些奇怪。 现在它们被视为在名称查找期间由其引用物取代的重定向,这与这种假设的用法更一致。

英文:

Absent a direct statement on the subject in Design & Evolution of C++, it’s hard to reliably infer intent for something like this. That said, until recently, the standard described using-declarations as introducing declarations as synonyms for the named declarations. In that view, it would be more than a little strange to have a member declaration belong to a block scope. Now they are considered to be redirects that are replaced by their referents during name lookup, which would be more consistent with this notional usage.

huangapple
  • 本文由 发表于 2023年1月8日 23:29:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049009.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定