【问题标题】:Polymorphism and overloaded functions with different signatures具有不同签名的多态性和重载函数
【发布时间】:2013-10-09 09:40:18
【问题描述】:

我想做的:一个简单的存储类,定义为模板尽可能通用。并且能够从这个类派生另一个,它可以接受任何东西,将其转换为int(算法在这里不相关),并将其存储在底层类中。

但是,这并不像预期的那样工作。这是我写的最小测试用例:

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;
}

当然,这是行不通的:

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)

有没有办法强制编译器使用 B 类的方法定义,或者这是一个真的坏主意?

--

编辑:公开继承。

【问题讨论】:

    标签: c++ class templates polymorphism


    【解决方案1】:

    首先,正如@GermanDiago 指出的那样,您正在使用私有继承,因此您会收到“无法访问基类”错误。公开更改 B 以从 A&lt;int&gt; 派生。

    即便如此,这也无法解决问题。名称查找基于静态类型。当您有一个指向A&lt;int&gt; 的指针时,通过该指针访问成员只会查看A&lt;int&gt; 的成员。

    您必须通过输入B 访问才能看到B 的成员:

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

    当然,如果我正确理解您的问题,这不是您真正想要的。你可以看看Curiously Recurring Template Pattern

    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

    当然,这有 B 成为 A 类型的一部分的缺点。我认为在仍然保留编译时间的同时没有办法解决这个问题。

    【讨论】:

    • 感谢您的有用解释。显然,我得再想一想……
    【解决方案2】:

    您必须使用公共继承:

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

    is-c++ 中的关系是通过公共继承实现的。您当前使用的是私有继承。

    【讨论】:

    • 是的,但这仍然不允许通过指向 A 的指针调用 B::f
    • 谢谢。简单的错误,我刚刚纠正了。仍然没有解决主要问题:/
    猜你喜欢
    • 2018-07-16
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    相关资源
    最近更新 更多