Rule A7-3-1 (required, implementation, automated)

All overloads of a function shall be visible from where it is called.

Rationale

Additional identifiers introduced by a using declaration makes only prior declarations of this identifier visible. Any potential subsequent declarations will not be added to the current scope, which may lead to unexpected results and developers confusion. Overriding or overloading a member function in a derived class causes other member functions with the same name to be hidden. Thus, a potential function call may result in a different function being called depending on if the call was made using the derived or base class reference/pointer. Introducing hidden names into the derived class by a using declaration helps to avoid such misleading situations.

Example

// $Id: A7-3-1.cpp 312801 2018-03-21 16:17:05Z michal.szczepankiewicz $
#include <cstdint>

class Base
{
public:
void P(uint32_t);

virtual void V(uint32_t);
virtual void V(double);

};

class NonCompliant : public Base
{
public:
//hides P(uint32_t) when calling from the
//derived class
void P(double);
//hides V(uint32_t) when calling from the
//derived class
void V(double) override;
};

class Compliant : public Base
{
public:
//both P(uint32_t) and P(double) available
//from the derived class
using Base::P;
void P(double);

//both P(uint32_t) and P(double)
using Base::V;
void V(double) override;

};

void F1()
{
NonCompliant d{};
d.P(0U); // D::P (double) called
Base& b{d};
b.P(0U); // NonCompliant::P (uint32_t) called

d.V(0U); // D::V (double) called
b.V(0U); // NonCompliant::V (uint32_t) called

}

void F2()
{
Compliant d{};
d.P(0U); // Compliant::P (uint32_t) called

Base& b{d};
b.P(0U); // Compliant::P (uint32_t) called

d.V(0U); // Compliant::V (uint32_t) called
b.V(0U); // Compliant::V (uint32_t) called

}

namespace NS
{
void F(uint16_t);
}

//includes only preceding declarations into
//the current scope
using NS::F;

namespace NS
{
void F(uint32_t);
}

void B(uint32_t b)
{
//non-compliant, only F(uint16_t) is available
//in this scope
F(b);
}

See also

MISRA C++ 2008 [7]: 7-3-5: Multiple declarations for an identifier in the same namespace shall not straddle a using-declaration for that identifier. HIC++ v4.0 [9]: 13.1.1: Ensure that all overloads of a function are visible from where it is called. Rule M7-3-6 (required, implementation, automated) Using-directives and using-declarations (excluding class scope or function scope usingdeclarations) shall not be used in header files. See MISRA C++ 2008 [7] See: Using-declaration [16] concerns an inclusion of specific type, e.g. using std::string.