模板派生类之间的转换运算符

时间:2013-12-18 18:31:31

标签: c++ templates inheritance

我有以下模板类, 我需要弄清楚如何在派生模板类之间实现转换运算符。

template<class T>
class Base
{
public:
    Base () { }

    template <class U>
    operator Base<U>()
    {
        return Base<U> (v);
    }

    virtual double getV() = 0;

};

class D1: public Base<D1>
{
public:

    D1(int j) 
    {
        i = j;
    }

    double getV() const { return i; }

    template <class U>
    operator Base<U>()
    {
        return Base<U>(getV());
    }

private:
    int i;
};

class D2: public Base<D2>
{
public:

    D2(int j) 
    {
        i2 = j;
    }

    double getV() const { return i2; }

    template <class U>
    operator Base<U>()
    {
        return Base<U>(getV());
    }

private:
    int i2;
};

如何实现以下目标?

D1 d1(3);
D2 d2 = d1;  //conversion from 'D1' to non-scalar type 'D2' requested

如果设计本身听起来还是应该做其他事情?

请让我知道你的想法

4 个答案:

答案 0 :(得分:0)

很难说你想要做什么,但我认为你不能按照描述去做。

如果你真的想拥有一个通用接口,你需要声明一个包含你的代码所需的所有方法和属性的公共基类,并让这两个类派生出来。然后,您可以始终转换为基类。

事实上这似乎是理想的。特别是因为如果需要,您始终可以使用虚方法自定义基类中的行为。

如果这在您当前的任务中不起作用,也许您应该更多地讨论为什么需要这个。

答案 1 :(得分:0)

您要为D2编写一个构造函数,该构造函数需要const D1&,或者您在D1中编写一个返回D2的转换运算符。您必须决定执行此转换的含义并适当地实施转换。

答案 2 :(得分:0)

您可以在派生类中添加一个构造函数,该构造函数采用Base模板:

template <class U>
D2(const Base<U> &other)
{
  i2 = other.getV();
} 

但不确定它是否符合您的需求。

答案 3 :(得分:0)

在您的示例中,我没有看到使用CRTP的原因。

Base的特化都具有不依赖于模板参数的虚拟成员函数。您的代码建议此虚拟成员函数可用于访问创建从Base的特化派生的任何类的实例所需的所有数据。如果我们遵循这个假设,人们可能会想到:

class Base
{
public:
    virtual double getV() const = 0;
};

class D1 : public Base
{
    int i;
public:
    D1(int);
    virtual double getV() const { return i; }
};

class D2 : public Base
{
    int i;
public:
    D2(int);
    virtual double getV() const { return i; }
};

这仍然不允许转换。但是,在这里添加它们非常简单:

class D1 : public Base
{
    int i;
public:
    D1(int);
    D1(Base const& p) : D1(p.getV()) {}
    virtual double getV() const { return i; }
};

D1而不是Base应该允许此转换,因为只有D1知道构建它所需的数据。


如果此处未显示的内容需要CRTP,您仍然可以使用公共基类:

class Common_base
{
public:
    virtual double getV() const = 0;
};

template<class T>
class Base : public Common_base
{
};

class D1 : public Base<D1>
{
    int i;
public:
    D1(int);
    D1(Common_base const& p) : D1(p.getV()) {}
    virtual double getV() const { return i; }
};

如果出于某种原因,转换需要CRTP,您仍然可以使用转换构造函数模板:

template<class T>
class Base
{
public:
    virtual double getV() const = 0; // whyever
};

class D1 : public Base
{
    int i;
public:
    D1(int);
    template<class U>
    D1(Base<U> const& p) : D1(p.getV()) {}
    virtual double getV() const { return i; }
};