C++ Overloaded Virtual Function Warning by Clang

c++ overloaded virtual function warning by clang?

This warning is there to prevent accidental hiding of overloads when overriding is intended. Consider a slightly different example:

struct chart; // let's pretend this exists
struct Base
{
virtual void* get(char* e);
};

struct Derived: public Base {
virtual void* get(chart* e); // typo, we wanted to override the same function
};

As it is a warning, it doesn't necessarily mean it is a mistake, but it might indicate one. Usually such warnings have a means of shutting them off by being more explicit and letting the compiler know you did intend what you wrote. I believe in this case you can do the following:

struct Derived: public Base {
using Base::get; // tell the compiler we want both the get from Base and ours
virtual void * get(char* e, int index);
};

solve clang-12 overloaded-virtual warning

Declaring one of the two overloads in the derived class, but not the other, will cause name lookup from the derived class to find only the one declared in the derived class.

So with your code you will not be able to call e.g. tf.encodePixels(foo::bar{}).

If you don't want to repeat all overloads in the derived class, you can import all of them via a using declaration in TIFFFormat:

using ImageFormat::encodePixels;

If you don't care or intent the overload to not be reachable from the derived class, then the warning is not relevant to you.

Hiding overloaded virtual function

It complains that doit is hidden in Derived. A fix:

struct Derived : I12 {
using I12::doit; // Bring all doit declarations from I12 into this scope.
void doit(int) override {}
};

Overloaded virtual function warning

My guess is that you have to define a pure virtual function

struct Base
{
virtual void funccall(const String e = "")=0;
};

or define a body for this method

struct Base
{
virtual void funccall(const String e = ""){};
};

Addition to the post:

#include "stdafx.h"
#include <string>

class base
{
public:
virtual void funccall(const std::string e = "") {}
};
class derived : public base
{

void funccall() {};
void funccall(char *e, int index) {};
};

int main()
{
return 0;
}

Hiding a private overloaded virtual function?

After all, DB cannot even see the hidden function (which might even be named the same by coincidence).

Accessibility and visibility are different concepts in C++. DA::f() is by default visible inside DB (and then hidden by DB::f()), but it is not accessible, because it is private inside DA, and DB is not a friend of DA. One could argue that hiding a function that is inaccessible is harmless, because it cannot be called anyway. However, the distinction between hidden and inaccessible can be significant because visible and inaccessible functions do participate in overload resolution. If db is an object of type DB, then what does db.f(0) do? If DA::f() is visible but inaccessible, it will be selected as best match and the compiler will emit a diagnostic because it is inaccessible and therefore cannot be called. If DA::f() is hidden, however, the compiler will select the overload that accepts a pointer instead, and treat the literal 0 as a null pointer.

hidden overloaded virtual function with more than 2 classes

The declaration of void visit(B&) or any declaration a member named visit (it could have been a data member int visit;) in visitor3 hides any member of a parent called visit.

Here the warning of the compiler is more a goodies. It recognized a common mistake pattern which consists in overriding a base virtual member function without taking care over of overloads. But it does not detect all hidden names, or does not warn for all of them. Whatsoever, all visit from visitor1 and visitor2 are hidden.

Additional answer: The using declaration that name members of a base class is a declaration inside the derived class of all the members in the base class that have that name and are visible. So this effectively include members that where also declared by a using declaration in the base class.

(These members declared by a using declaration behave closely as if they were actual members first declared in that class. Even overload resolution considers their implied object parameter to be of the type of the derived class.)



Related Topics



Leave a reply



Submit