Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

Name-lookup.html 9.7KB

před 3 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- Copyright (C) 1988-2020 Free Software Foundation, Inc.
  4. Permission is granted to copy, distribute and/or modify this document
  5. under the terms of the GNU Free Documentation License, Version 1.3 or
  6. any later version published by the Free Software Foundation; with the
  7. Invariant Sections being "Funding Free Software", the Front-Cover
  8. Texts being (a) (see below), and with the Back-Cover Texts being (b)
  9. (see below). A copy of the license is included in the section entitled
  10. "GNU Free Documentation License".
  11. (a) The FSF's Front-Cover Text is:
  12. A GNU Manual
  13. (b) The FSF's Back-Cover Text is:
  14. You have freedom to copy and modify this GNU Manual, like GNU
  15. software. Copies published by the Free Software Foundation raise
  16. funds for GNU development. -->
  17. <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
  18. <head>
  19. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  20. <title>Name lookup (Using the GNU Compiler Collection (GCC))</title>
  21. <meta name="description" content="Name lookup (Using the GNU Compiler Collection (GCC))">
  22. <meta name="keywords" content="Name lookup (Using the GNU Compiler Collection (GCC))">
  23. <meta name="resource-type" content="document">
  24. <meta name="distribution" content="global">
  25. <meta name="Generator" content="makeinfo">
  26. <link href="index.html#Top" rel="start" title="Top">
  27. <link href="Option-Index.html#Option-Index" rel="index" title="Option Index">
  28. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  29. <link href="C_002b_002b-Misunderstandings.html#C_002b_002b-Misunderstandings" rel="up" title="C++ Misunderstandings">
  30. <link href="Temporaries.html#Temporaries" rel="next" title="Temporaries">
  31. <link href="Static-Definitions.html#Static-Definitions" rel="prev" title="Static Definitions">
  32. <style type="text/css">
  33. <!--
  34. a.summary-letter {text-decoration: none}
  35. blockquote.indentedblock {margin-right: 0em}
  36. blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
  37. blockquote.smallquotation {font-size: smaller}
  38. div.display {margin-left: 3.2em}
  39. div.example {margin-left: 3.2em}
  40. div.lisp {margin-left: 3.2em}
  41. div.smalldisplay {margin-left: 3.2em}
  42. div.smallexample {margin-left: 3.2em}
  43. div.smalllisp {margin-left: 3.2em}
  44. kbd {font-style: oblique}
  45. pre.display {font-family: inherit}
  46. pre.format {font-family: inherit}
  47. pre.menu-comment {font-family: serif}
  48. pre.menu-preformatted {font-family: serif}
  49. pre.smalldisplay {font-family: inherit; font-size: smaller}
  50. pre.smallexample {font-size: smaller}
  51. pre.smallformat {font-family: inherit; font-size: smaller}
  52. pre.smalllisp {font-size: smaller}
  53. span.nolinebreak {white-space: nowrap}
  54. span.roman {font-family: initial; font-weight: normal}
  55. span.sansserif {font-family: sans-serif; font-weight: normal}
  56. ul.no-bullet {list-style: none}
  57. -->
  58. </style>
  59. </head>
  60. <body lang="en">
  61. <a name="Name-lookup"></a>
  62. <div class="header">
  63. <p>
  64. Next: <a href="Temporaries.html#Temporaries" accesskey="n" rel="next">Temporaries</a>, Previous: <a href="Static-Definitions.html#Static-Definitions" accesskey="p" rel="prev">Static Definitions</a>, Up: <a href="C_002b_002b-Misunderstandings.html#C_002b_002b-Misunderstandings" accesskey="u" rel="up">C++ Misunderstandings</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
  65. </div>
  66. <hr>
  67. <a name="Name-Lookup_002c-Templates_002c-and-Accessing-Members-of-Base-Classes"></a>
  68. <h4 class="subsection">14.7.2 Name Lookup, Templates, and Accessing Members of Base Classes</h4>
  69. <a name="index-base-class-members"></a>
  70. <a name="index-two_002dstage-name-lookup"></a>
  71. <a name="index-dependent-name-lookup"></a>
  72. <p>The C++ standard prescribes that all names that are not dependent on
  73. template parameters are bound to their present definitions when parsing
  74. a template function or class.<a name="DOCF5" href="#FOOT5"><sup>5</sup></a> Only names that are dependent are looked up at the point
  75. of instantiation. For example, consider
  76. </p>
  77. <div class="smallexample">
  78. <pre class="smallexample"> void foo(double);
  79. struct A {
  80. template &lt;typename T&gt;
  81. void f () {
  82. foo (1); // <span class="roman">1</span>
  83. int i = N; // <span class="roman">2</span>
  84. T t;
  85. t.bar(); // <span class="roman">3</span>
  86. foo (t); // <span class="roman">4</span>
  87. }
  88. static const int N;
  89. };
  90. </pre></div>
  91. <p>Here, the names <code>foo</code> and <code>N</code> appear in a context that does
  92. not depend on the type of <code>T</code>. The compiler will thus require that
  93. they are defined in the context of use in the template, not only before
  94. the point of instantiation, and will here use <code>::foo(double)</code> and
  95. <code>A::N</code>, respectively. In particular, it will convert the integer
  96. value to a <code>double</code> when passing it to <code>::foo(double)</code>.
  97. </p>
  98. <p>Conversely, <code>bar</code> and the call to <code>foo</code> in the fourth marked
  99. line are used in contexts that do depend on the type of <code>T</code>, so
  100. they are only looked up at the point of instantiation, and you can
  101. provide declarations for them after declaring the template, but before
  102. instantiating it. In particular, if you instantiate <code>A::f&lt;int&gt;</code>,
  103. the last line will call an overloaded <code>::foo(int)</code> if one was
  104. provided, even if after the declaration of <code>struct A</code>.
  105. </p>
  106. <p>This distinction between lookup of dependent and non-dependent names is
  107. called two-stage (or dependent) name lookup. G++ implements it
  108. since version 3.4.
  109. </p>
  110. <p>Two-stage name lookup sometimes leads to situations with behavior
  111. different from non-template codes. The most common is probably this:
  112. </p>
  113. <div class="smallexample">
  114. <pre class="smallexample"> template &lt;typename T&gt; struct Base {
  115. int i;
  116. };
  117. template &lt;typename T&gt; struct Derived : public Base&lt;T&gt; {
  118. int get_i() { return i; }
  119. };
  120. </pre></div>
  121. <p>In <code>get_i()</code>, <code>i</code> is not used in a dependent context, so the
  122. compiler will look for a name declared at the enclosing namespace scope
  123. (which is the global scope here). It will not look into the base class,
  124. since that is dependent and you may declare specializations of
  125. <code>Base</code> even after declaring <code>Derived</code>, so the compiler cannot
  126. really know what <code>i</code> would refer to. If there is no global
  127. variable <code>i</code>, then you will get an error message.
  128. </p>
  129. <p>In order to make it clear that you want the member of the base class,
  130. you need to defer lookup until instantiation time, at which the base
  131. class is known. For this, you need to access <code>i</code> in a dependent
  132. context, by either using <code>this-&gt;i</code> (remember that <code>this</code> is of
  133. type <code>Derived&lt;T&gt;*</code>, so is obviously dependent), or using
  134. <code>Base&lt;T&gt;::i</code>. Alternatively, <code>Base&lt;T&gt;::i</code> might be brought
  135. into scope by a <code>using</code>-declaration.
  136. </p>
  137. <p>Another, similar example involves calling member functions of a base
  138. class:
  139. </p>
  140. <div class="smallexample">
  141. <pre class="smallexample"> template &lt;typename T&gt; struct Base {
  142. int f();
  143. };
  144. template &lt;typename T&gt; struct Derived : Base&lt;T&gt; {
  145. int g() { return f(); };
  146. };
  147. </pre></div>
  148. <p>Again, the call to <code>f()</code> is not dependent on template arguments
  149. (there are no arguments that depend on the type <code>T</code>, and it is also
  150. not otherwise specified that the call should be in a dependent context).
  151. Thus a global declaration of such a function must be available, since
  152. the one in the base class is not visible until instantiation time. The
  153. compiler will consequently produce the following error message:
  154. </p>
  155. <div class="smallexample">
  156. <pre class="smallexample"> x.cc: In member function `int Derived&lt;T&gt;::g()':
  157. x.cc:6: error: there are no arguments to `f' that depend on a template
  158. parameter, so a declaration of `f' must be available
  159. x.cc:6: error: (if you use `-fpermissive', G++ will accept your code, but
  160. allowing the use of an undeclared name is deprecated)
  161. </pre></div>
  162. <p>To make the code valid either use <code>this-&gt;f()</code>, or
  163. <code>Base&lt;T&gt;::f()</code>. Using the <samp>-fpermissive</samp> flag will also let
  164. the compiler accept the code, by marking all function calls for which no
  165. declaration is visible at the time of definition of the template for
  166. later lookup at instantiation time, as if it were a dependent call.
  167. We do not recommend using <samp>-fpermissive</samp> to work around invalid
  168. code, and it will also only catch cases where functions in base classes
  169. are called, not where variables in base classes are used (as in the
  170. example above).
  171. </p>
  172. <p>Note that some compilers (including G++ versions prior to 3.4) get these
  173. examples wrong and accept above code without an error. Those compilers
  174. do not implement two-stage name lookup correctly.
  175. </p>
  176. <div class="footnote">
  177. <hr>
  178. <h4 class="footnotes-heading">Footnotes</h4>
  179. <h3><a name="FOOT5" href="#DOCF5">(5)</a></h3>
  180. <p>The C++ standard just uses the
  181. term &ldquo;dependent&rdquo; for names that depend on the type or value of
  182. template parameters. This shorter term will also be used in the rest of
  183. this section.</p>
  184. </div>
  185. <hr>
  186. <div class="header">
  187. <p>
  188. Next: <a href="Temporaries.html#Temporaries" accesskey="n" rel="next">Temporaries</a>, Previous: <a href="Static-Definitions.html#Static-Definitions" accesskey="p" rel="prev">Static Definitions</a>, Up: <a href="C_002b_002b-Misunderstandings.html#C_002b_002b-Misunderstandings" accesskey="u" rel="up">C++ Misunderstandings</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Option-Index.html#Option-Index" title="Index" rel="index">Index</a>]</p>
  189. </div>
  190. </body>
  191. </html>