Domanda

Here is a sample code:

#include <memory>

class A {
  public:
    template <class T> void f(std::unique_ptr<T>, int) {}

  private:
    virtual void f(int) = 0;
};

class B: public A {
  public:
    using A::f;

  private:
    virtual void f(int) override {}
};

int main() {
  std::unique_ptr<float> a;
  B* b = new B;
  b->f(std::move(a), 1);

  return 0;
}

When I compile it with clang++, I get an error:

'f' is a private member of 'A'
using A::f;
         ^

How to make the template method f(std::unique_ptr<T>, int) visible from class B?


Note: if the virtual method A::f(int) is moved to a public section - everything works fine.

È stato utile?

Soluzione

By giving it distinct name from the completely unrelated private virtual f.

Having an overloaded function where different overloads have different access control level neither works nor makes sense. You should only use the same name if the functions actually do the same (or comparable given the arguments) thing, but than it does not make sense to make one public and one private.

If you have a public wrapper over private virtual (which is common, see e.g. std::basic_streambuf), just add suitable prefix/suffix to one of them (std::basic_streambuf uses pub on the public, but it usually makes more sense to add priv, impl or _ to the private virtual.

Altri suggerimenti

You can not use using for this as using can not distinguish between the template and the virtual f. What does work is a simple forwarder:

class B: public A {
public:
  template <class T> void f(std::unique_ptr<T> p, int i)
  {
    A::f<T>(std::move(p),i);
  }

private:
  virtual void f(int) override {}
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top