In C++ template function, why does dependent function call give "not declared" error?
<p>Inside a C++ template function foo(), a call to ::bar(TT*) gives the following error under gcc 4.4.3:</p>

<pre><code>g++ -o hello.o -c -g hello.cpp
hello.cpp: In function 'void foo(std::vector&lt;TT*, std::allocator&lt;TT*&gt; &gt;&amp;)':
hello.cpp:8: error: '::bar' has not been declared
</code></pre>

<p>Here's the offending code:</p>

<pre><code>// hello.cpp

#include &lt;vector&gt;

template&lt;typename TT&gt; void foo(std::vector&lt;TT*&gt; &amp;vec)
{
    TT *tt;
    ::bar(tt);
    vec.push_back(tt);
}

class Blah
{
};

void bar(Blah *&amp;)
{
}

int main(int argc, char *argv[])
{
    std::vector&lt;Blah*&gt; vec;
    foo(vec);

    return 0;
}
</code></pre>

<p>C++ distinguishes between symbols that are dependent on the template parameter (TT, here) and those symbols that are independent and can be evaluated immediately.</p>

<p>Clearly, the compiler thinks my ::bar(TT*) call is independent and tries to resolve it immediately. Just as clearly, that function call <strong>is</strong> dependent on TT because the function call takes a parameter of type TT*, so the compiler should wait until the foo(vec) instantiation to resolve ::bar(TT*).</p>

<p>Is this a gcc bug or am I missing something subtle about C++ templates?</p>

<p>EDIT: here's a slightly more complicated example with two versions of ::bar() to clarify that declaration order is not the issue with my problem. When parsing the template, the compiler has <strong>no</strong> way of knowing if main() down below is going to instantiate the template function with TT=Blah or with TT=Argh. Therefore the compiler should not be giving an error until <strike>line 35</strike> line 28 at the earliest (if ever). But the error is given for <strike>line 8</strike> line 16.</p>

<p>EDIT #2: improved this example.</p>

<p>EDIT #3: added corrections to this example to make it work as desired. The bar(tt) now correctly refers to bar(Blah*). Rationale given below. (Thanks everyone).</p>

<pre><code>// hello.cpp
#include &lt;vector&gt;

class XX {};
void bar(XX*) {}

class CC {
public:
    void bar();
    void bar(int *);
    void bar(float *);

    template&lt;typename TT&gt; static void foo(std::vector&lt;TT*&gt; &amp;vec);
};

template&lt;typename TT&gt;
void CC::foo(std::vector&lt;TT*&gt; &amp;vec) {
    using ::bar;
    TT *tt;
    bar(tt);
    vec.push_back(tt);
}

class Argh {};
void bar(Argh *&amp;aa) { aa = new Argh; }

class Blah {};
void bar(Blah *&amp;bb) { bb = new Blah; }

int main(int argc, char *argv[]) {
    std::vector&lt;Blah*&gt; vec;
    CC::foo(vec);
    return 0;
}
</code></pre>
