How to resolve name conflict when using c headers?

I am currently doing socket programming using C / C ++. To be able to use a slightly cleaner interface and a more OO structure, I decided to write some simple wrapper classes around parts of the socket API, but in doing so I ran into a problem:

Given the following code:

// Global method
int foo(int x)
{
    return x;
}

// Class that calls the global method
class FooBar
{
public:
    void foo() { return; };
    void baz() { foo(1); }
};

      

g ++ gives the following error message:

test.cpp: In member functionvoid FooBar::baz()’:
test.cpp:10: error: no matching function for call toFooBar::foo(int)test.cpp:9: note: candidates are: void FooBar::foo()

      

Renaming the class method solves the problem.

Why is there some kind of naming conflict even though the method signatures are different? What's the best way to fix this?

Thanks / Eric

+1


source to share


3 answers


The problem is that it first looks in the scope of your class and finds the function foo. Then the search will stop and the compiler will try to match the arguments. Since it only has one function foo in that scope in your class, no function call is made.

You need to explicitly state that you want to call the free function:

::foo(1);

      



Another solution is to declare a function in baz:

void baz() { int foo(int); foo(1); }

      

The scope where foo is assumed to be defined as the surrounding namespace of your class.

+8


source


You should use an attempt at resolving scope:



:: Foo (1);

+3


source


Decision:

void baz() { ::foo(1); }

      

"Why is there some name conflict even though the method signatures are different?"

Since C ++ always, always, looks for names first. When it finds a name in the appropriate area, it then checks what signatures are available for that name in that area. Thus, a member function foo()

hides a free function foo(int)

anywhere it is in scope (that is, in other member functions of the class).

The following code will not compile for the same reason:

struct A {
    virtual void foo(int) = 0;
    // attempt to provide a useful helper
    virtual void foo() { foo(23); }
};

struct B : public A {
    void foo(int i) {
        std::cout << i << "\n";
    }
};

int main() {
    B b;
    b.foo(); // oops, can't find foo(), because class B hid it
    A &a = b;
    a.foo(); // that works. So much for Liskov substitution principle.
}

      

B, as written, is broken because it removes functionality from its base class (although only if it is called B, not when it is called A). litb provides a link in the comment below explaining how to unblock it.

+2


source







All Articles