简体   繁体   English

多态性和具有不同签名的重载函数

[英]Polymorphism and overloaded functions with different signatures

What I want to do : a simple storage class, defined as a template to be as general as possible. 我想做的事:一个简单的存储类,定义为尽可能通用的模板。 And being able to derive from this class another, that would accept anything, convert it to int (the algorithm is not relevant here), and store it in the underlying class. 并且能够从这个类派生另一个,它将接受任何东西,将其转换为int (算法在这里不相关),并将其存储在底层类中。

But, this doesn't quite work as expected. 但是,这并没有像预期的那样奏效。 Here is the minimal test case I wrote: 这是我写的最小测试用例:

template<typename T>
class A {
  public:
    void f(T& foo) { }
};

class B : public A<int> {
  public:
    template<typename T>
    void f(T& foo) { }
};

int main() {
  A<int>* ptr = new B;
  ptr->f("foo");
  delete ptr;
  return 0;
}

Of course, this doesn't work: 当然,这不起作用:

pierre@raringbeast:~/Workspace/Test/src$ icpc -o Test Test.cpp 
Test.cpp(16): error: a reference of type "int &" (not const-qualified) cannot
be initialized with a value of type "const char [4]"
    ptr->f("foo");
           ^

compilation aborted for Test.cpp (code 2)

Is there any way to force the compiler to use the method definition from the B class, or is this a really bad idea? 有没有办法强制编译器使用B类中的方法定义,或者这是一个非常糟糕的主意?

-- -

Edit : Made the inheritance public. 编辑 :继承公开。

First off, as @GermanDiago pointed out, you're using private inheritance, so you're getting the "base class inaccessible" error. 首先,正如@GermanDiago指出的那样,你正在使用私有继承,所以你得到的“基类无法访问”错误。 Change B to derive from A<int> publically. B更改为公共派生自A<int>

Even so, this won't fix the issue. 即便如此,这也无法解决问题。 Name lookup is based on static types. 名称查找基于静态类型。 When you have a pointer to A<int> , accessing members through that pointer will only look at the members of A<int> . 当你有一个指向A<int>的指针时,通过该指针访问成员只会查看A<int>的成员。

You have to access through type B to see B 's members: 您必须通过B类访问以查看B的成员:

int main() {
  B* ptr = new B;
  ptr->f("foo");
  delete ptr;
  return 0;
}

Of course, if I understand your question correctly, this is not what you really want. 当然,如果我理解你的问题,这不是你真正想要的。 You might look at the Curiously Recurring Template Pattern instead. 您可能会查看奇怪的重复模板模式

template <class T, class Derived>
class A {
  public:
    template <class U>
    void f(U& bar) {
      static_cast<Derived*>(this)->f(bar);
    }

    void f(T& foo) {

    }
};


class B : public A<int, B>
{
  public:
    template <class T>
    void f(T &foo) {
      //will be called from A's f(U&)
    }
};


int main() {
  A<int, B>* ptr = new B;
  ptr->f("foo");
  delete ptr;
  return 0;
}

Live example 实例

Of course, this has the downside of B becoming part of A 's type. 当然,这有点B成为A类型的一部分。 I don't think there's a way out of this while still remaining compile-time. 我认为还有一种方法可以解决这个问题,同时仍然保持编译时间。

You must use public inheritance: 您必须使用公共继承:

class B : public A<int> {
    //...
}

is-a relationship in c++ is through public inheritance. 是 - c ++中的关系是通过公共继承。 Private inheritance is what you are currently using. 私有继承是您当前使用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM