<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[g++] call of a parent method of parent template class fails]]></title><description><![CDATA[<p>code:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

template&lt;typename type&gt;
struct Parent {
    void foo() { std::cout &lt;&lt; &quot;Parent::foo()&quot; &lt;&lt; std::endl; }
};

template&lt;typename type&gt;
struct Child : Parent&lt;type&gt; {
    void bar() { foo(); } // line 10
};

int main()
{
    Parent&lt;int&gt; p;
    p.foo();
}
</code></pre>
<p>g++ output:</p>
<pre><code>$ g++ test.cpp -o test
test.cpp: In member function `void Child&lt;type&gt;::bar()':
test.cpp:10: error: there are no arguments to `foo' that depend on a template parameter, so a declaration of `foo' must be available
test.cpp:10: error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
</code></pre>
<p>I can get rid of this error by using <em>this-&gt;foo();</em> or <em>using Parent&lt;type&gt;::foo;</em>, but I don't understand why this doesn't work my way.</p>
<p>greetings and thanks in advance</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/165851/g-call-of-a-parent-method-of-parent-template-class-fails</link><generator>RSS for Node</generator><lastBuildDate>Tue, 15 Sep 2026 02:28:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/165851.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 23 Nov 2006 16:07:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to [g++] call of a parent method of parent template class fails on Thu, 23 Nov 2006 16:07:39 GMT]]></title><description><![CDATA[<p>code:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

template&lt;typename type&gt;
struct Parent {
    void foo() { std::cout &lt;&lt; &quot;Parent::foo()&quot; &lt;&lt; std::endl; }
};

template&lt;typename type&gt;
struct Child : Parent&lt;type&gt; {
    void bar() { foo(); } // line 10
};

int main()
{
    Parent&lt;int&gt; p;
    p.foo();
}
</code></pre>
<p>g++ output:</p>
<pre><code>$ g++ test.cpp -o test
test.cpp: In member function `void Child&lt;type&gt;::bar()':
test.cpp:10: error: there are no arguments to `foo' that depend on a template parameter, so a declaration of `foo' must be available
test.cpp:10: error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
</code></pre>
<p>I can get rid of this error by using <em>this-&gt;foo();</em> or <em>using Parent&lt;type&gt;::foo;</em>, but I don't understand why this doesn't work my way.</p>
<p>greetings and thanks in advance</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1180139</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1180139</guid><dc:creator><![CDATA[sry, only english]]></dc:creator><pubDate>Thu, 23 Nov 2006 16:07:39 GMT</pubDate></item><item><title><![CDATA[Reply to [g++] call of a parent method of parent template class fails on Thu, 23 Nov 2006 17:10:29 GMT]]></title><description><![CDATA[<blockquote>
<p>I can get rid of this error by using this-&gt;foo(); or using Parent&lt;type&gt;::foo;, but I don't understand why this doesn't work my way</p>
</blockquote>
<p>This is a peculiarity of the so called two-phase-name-lookup.<br />
Specifically, a non-dependent name is never looked up in a base class that depends on a template paramter.</p>
<p>C++ Standard schrieb:</p>
<blockquote>
<p>In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, if a base class of this template depends on a template-parameter, the base class scope is not examined during name lookup until the class template is instantiated.</p>
</blockquote>
<p>In your example, the unqualified call to foo() can only be bound to a function declared in Child or in namespce-scope. The base of Child is not considered because it depends on the template-parameter type. The rationale for this rule is that otherwise name lookup would have to be delayed until templates are instantiated. Otherwise succeeding specialization would pose a problem<br />
Consider:</p>
<pre><code class="language-cpp">template&lt;typename type&gt;
struct Parent {
    void foo() { std::cout &lt;&lt; &quot;Parent::foo()&quot; &lt;&lt; std::endl; }
};

template&lt;typename type&gt;
struct Child : Parent&lt;type&gt; {
    void bar() { foo(); } // line 10
};

template &lt;&gt;
struct Parent&lt;int&gt; {

};

void f() {
  Child&lt;int&gt; c;
  c.bar();
}
</code></pre>
<p>As you can see, the compiler may not simply bind a name to a name contained in a dependent base class, because the meaning of this name may change when the template is specialized.</p>
<p>So in order to not having to delay name-lookup to instantiation time completly, the Standard distinguishes two types of names: non-dependent names are looked up as soon as the definition of a template is seen. Dependent names on the other hand are only looked up when a template is instantiated. Qualifying foo with this-&gt; or Parent&lt;type&gt; makes it a dependent name and thus forces the compiler to delay name-lookup until the template is instantiated.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1180182</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1180182</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Thu, 23 Nov 2006 17:10:29 GMT</pubDate></item></channel></rss>