Sergey L.
Sergey L.

Reputation: 22552

Linux gcc picking trying to instantiate a template where function should be

I have the following sample code that reproduces my error:

// non-namespacing this compiles as expected
namespace n
{
    template <typename T>
    void foo(T const & t)
    {
        t.doesnt_have_this_method();
    }
}

template <typename T>
void bar(T const & t)
{
    // picks the template over the overload
    n::foo(t);
}

namespace n
{
    // function overload
    void foo(int const &);
}

void n::foo(int const &) {}


int main()
{
    int a;

    bar(a);
}

That code compiles fine on both MSVC 2010 and Solaris 8 compilers. But gcc4 (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42) fails with the error:

test.cpp: In function 'void n::foo(const T&) [with T = int]':
test.cpp:14:   instantiated from 'void bar(const T&) [with T = int]'
test.cpp:34:   instantiated from here
test.cpp:6: error: 'const int' has no member named 'doesnt_have_this_method'

The template bar doesn't seem to see the foo function overload. I want to figure out why this is happening. Three things that I know can alleviate the issue, but are difficult to enforce in a production environment:

  1. declaring foo(int const &) before bar. This is something that I can do in my prod code, but is difficult to enforce throughout the entire codebase in the future
  2. not putting foo in a namespace. This is something that I can't do because I am interfacing with another library.
  3. making the overload a template specialisation template<> void n::foo(int const &). Something that I can't do, because the declaration of foo(int const &) is out of my control.

Please help me understand on how to fix this. Why isn't the compiler picking the right function?

Upvotes: 2

Views: 79

Answers (1)

Jonathan Wakely
Jonathan Wakely

Reputation: 171373

In the definition of bar the only foo that is visible is the function template, because the other one hasn't been declared yet.

Upvotes: 4

Related Questions