Why is this compiling successfully?
Asked Answered
C

1

5

What is the reason which why this code compile :

#include <iostream>
using namespace std;
class being {
public:
  void running(char c) {
        cout << "No one know ";
    }
};
class human :public being {
public:
    using being::running;
    void running(char y) {
        cout << "I am a human";
    }
};

int main() {
    human o;
    o.running('A');
    return 0;
}


the output : "I am a human" 

I mean ( I am expecting having error (redefinition function in human class )) like this : this code compile :

#include <iostream>
using namespace std;
class being {
public:
    int v;
};
struct human :public being {
public:
    
    double v;

};

int main() {
    human o;
    o.v = 55.2;
    return 0;
}

but when i add ( using being::v )

#include <iostream>
using namespace std;
class being {
public:
    int v;
};
struct human :public being {
public:
    using being::v;

    double v;

};

int main() {
    human o;
    o.v = 55.2;
    return 0;
}

the error appear: error C2086: 'int being::v': redefinition

why this error did not appear in the first code ?

Chum answered 30/8, 2021 at 16:1 Comment(1)
Why are you expecting that? (It isn't; the word "using" does not have its normal English meaning.)Peptonize
R
8

This is expected behavior of using declaration.

If the derived class already has a member with the same name, parameter list, and qualifications, the derived class member hides or overrides (doesn't conflict with) the member that is introduced from the base class.

So human::running(char) hides being::running(char) instead of conflict.

EDIT

The 2nd code snippet is ill-formed. For data members, from the standard, [namespace.udecl]/10:

If a declaration named by a using-declaration that inhabits the target scope of another declaration potentially conflicts with it ([basic.scope.scope]), and either is reachable from the other, the program is ill-formed. If two declarations named by using-declarations that inhabit the same scope potentially conflict, either is reachable from the other, and they do not both declare functions or function templates, the program is ill-formed.

[Example 6:

...

namespace B {
  int i;
  ...
}

void func() {
  int i;
  using B::i;                           // error: conflicts
  ...
...

So you can't using being::v which conflicts with human::v. But for member functions, [namespace.udecl]/11:

The set of declarations named by a using-declarator that inhabits a class C does not include member functions and member function templates of a base class that correspond to (and thus would conflict with) a declaration of a function or function template in C.

[Example 7:

struct B {
  virtual void f(int);
  virtual void f(char);
  void g(int);
  void h(int);
};

struct D : B {
  using B::f;
  void f(int);      // OK: D​::​f(int) overrides B​::​f(int);

  using B::g;
  void g(char);     // OK

  using B::h;
  void h(int);      // OK: D​::​h(int) hides B​::​h(int)
};
...
Roslyn answered 30/8, 2021 at 16:4 Comment(2)
FYI the OP has updated the question, clarifying why they expected a redefinition error.Braynard
"human::running hides being::running" Not quite. human::running(char) hides being::running(char) but if there were any other signatures for being::running they would be visible as overloads of human::running(char) (This is the change that using makes, without the using declaration, then human::running(char) would indeed hide all signatures of being::running)Vaden

© 2022 - 2024 — McMap. All rights reserved.