从基类指针派生类的派生模板类型

时间:2018-09-07 20:03:19

标签: c++ templates inheritance

请考虑以下内容:

  1. 一个类 B
  2. 一个类 D ,其中
    • 源自类 B
    • 具有模板参数 T
    • 具有类型为 T
    • 的成员变量 x
  3. 具有 F 的模板函数
    • 模板参数 S
    • 类型为 S 的参数y。
  4. 指针 p ,其中
    • 具有类型 B *
    • 指向类参数 D 的对象 o ,其模板参数 T 等于 int
  5. 不能修改功能 F
  6. F不能直接从类B或D调用

进一步考虑,仅给出指针 p ,并且应使用等于成员变量的参数 y 调用 F 对象 o 的x (这意味着类型 S 等于 int )。

如何修改类 B D 来实现这一目标?我猜想需要某种机制来导出模板类型 T 。但是我不知道该怎么做。

以下是相关代码:

文件F.h:

#include <iostream>
//////////// Consider that the lines up to the next comment cannot be changed
template< typename S > void F( S y )
{
    std::cout << y <<  " of some type" << std::endl; 
}

template<> void F<>( int y )
{
    std::cout << y << " of int type." << std::endl; 
}
//////////// -----------------------------

文件BD.h:

// F.h cannot be included here
class B { };

template<typename T> class D : public B { public:  T x;  };

文件main.cpp:

#include "BD.h"
#include "F.h"
int main()
{
    D<int>  o;
    o.x  =  3;
    B* p = &o;

    // Obviously, the following line will not work:
    // F( p->x );

    // Obviously, the following will work:
    F( ( (D<int>*) p)->x );

    // However, consider that 
    //   1) only p is given and
    //   2) that it is not known that p points to an object of type D<int>.
    // How to modify B or D to be able to invoke the correct instantiation of F here
    // , i.e. that for the type of "int"?
    return 0;
}

2 个答案:

答案 0 :(得分:1)

你可能会

class B
{
public:
    virtual ~B() = default;
    virtual void f() const = 0;
};

template<typename T>
class D : public B
{
public:
    void f() const override { F(x); }
private:
    T x;
};

Demo

答案 1 :(得分:0)

您可以使用回调函数以及虚拟成员函数来调用它:

class B
{
public:
    virtual ~B() = default;
    virtual void call() const = 0;
};

template <typename T>
class D : public B
{
public:
    explicit D(T t, std::function<void(T)> cb)
        : x(std::move(t)),
          callback(std::move(cb))
    {
    }
    void call() const override
    {
        callback(x);
    }
private:
    T x;
    std::function<void(T)> callback;
};

int main()
{
    D<int> o(3, F<int>);
    B* p = &o;
    p->call();
)

Live Demo