views:

80

answers:

3

Hi, i am currently working on a C++ project where i have an abstract interface that is implemented later on. The interface also has a implemented method which my implementation doesn't override. My problem is that when using my implementation, the compiler(MSVC) doesn't see the interface method. What causes this, and how can i resolve it?

Here comes the code.

#include <string>
#include <vector>
using std::string;

class A
{
    public:
    string name;
};

class interface
{ 
public:
    virtual int num_foo() = 0;
    virtual A* foo(int) = 0;
    virtual A* foo(string &name){
     for ( int i(0); i < num_foo(); i++)
      if ( foo(i)->name == name )
       return foo(i);
     return 0;
    }
};

class implementation : public interface
{
public:
    virtual int num_foo() { return m_foos.size(); }
    virtual A* foo(int i) { 
     //check range 
     return &m_foos[i];
    }
    std::vector<A> m_foos;
};

int main(...)
{
    implementation impl;
    // impl is properly initialized here

    string name( "bar" );
    // here comes my problem, the MSVC compiler doesn't see foo(string &name)
    // and gives an error
    A *a = impl.foo( name );
}
+5  A: 

Name resolution happens before overload resolution. In impl.foo( name ), then compiler looks at the implementation class and finds only virtual A& foo(int i). It does not look at the base class as it has found a function with the right name.

To correct this use can add a using interface::foo declaration to the derived class to pull all of the base versions of foo into the derived class for the purposes of overload resolution. Usually, I'd prefer to avoid overloaded functions and I'd probably give the variants of foo different function names.

(Other errors are that you don't define string, vector or m_ones; you attempt to use -> instead of . on a reference and you attempt to return 0 in a function returning a reference to an A.)

Charles Bailey
+1 for a clear explanation as well as two proposed workarounds!
RichieHindle
Thanks for answering my question and foreseeing the bad code first provided.
christoff
+3  A: 

To re-publish base methods (such as foo(string)) in a subclass for overloading, add

  using interface::foo;

into class implementation.

Martin v. Löwis
Thanks for the fast and good answer!
christoff
+1  A: 
class implementation : public interface{
    public:
       using interface::foo;
       int num_foo() { return m_foos.size(); }
       A& foo(int i)
       {   //check range
           return m_ones[i];
       }
       vector<A> m_foos;
       vector<A> m_ones;
};
adatapost