微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从子类中提取嵌套类型并将其用于抽象父类中虚拟函数的函数签名中?

如何解决如何从子类中提取嵌套类型并将其用于抽象父类中虚拟函数的函数签名中?

我经常不得不在C ++中实现“类似容器”的类,而且我发现我常常忘记实现接口的一部分,以后会遇到问题。为了解决这个问题,我想创建一个抽象的Container类,如果没有实现任何必需的接口函数,我可以使我的容器类继承自该类。

问题在于容器类通常定义一个size_type,而我希望size()函数返回相应的size_type,无论底层容器是什么。

以下是我所谈论的内容的简化示例:

#include <vector>

// Abstract class
template <typename T>
class Container
{
public:
    virtual ~Container() = 0;

    //********************************************************************************
    // How do I tell it to return whatever "size_type" is for the child class?
    //********************************************************************************
    virtual typename ChildClass::size_type size() const = 0;
};

template <typename T>
Container<T>::~Container() = default;

// Concrete
template <typename T>
class MyVector final : public Container<T>
{
public:
    // size_type of the child class defined here
    using size_type = typename std::vector<T>::size_type;

    MyVector()
        : m_data()
    {}

    size_type size() const override
    {
        return m_data.size();
    }

private:
    std::vector<T> m_data;
};

size_type的抽象函数定义中,有什么方法可以引用子类的size()吗?


编辑

在应用CRTP之后(建议如下),我觉得自己距离更近了,但是仍然无法编译第二个实例化MyVector<double>对象的对象:

// Abstract class
template <typename T>
class Container {
  public:
    virtual ~Container() = default;

    // Still can't seem to resolve the type here
    virtual typename T::size_type size() const = 0;
};

// Concrete
template <typename T>
class MyVector final : private Container<MyVector<T>> {
  public:
    using size_type = typename std::vector<T>::size_type;
    using value_type = T;

    size_type size() const
    {
        return m_data.size()
    }

private:
    std::vector<T> m_data;
};

int main()
{
    // Fails to compile
    MyVector<double> v;
}

我收到编译器错误

错误C2039:'size_type':不是'MyVector'的成员

解决方法

answer到一个相关的问题,我发现了一些可行的方法。这有点丑陋,因为它要求我为我要实现的每个容器定义一个ContainerTraits结构,但确实可以完成工作。

template <typename T>
struct ContainerTraits;

// Abstract class
template <typename T>
class Container {
public:
    using size_type = typename ContainerTraits<T>::size_type;

    virtual ~Container() = default;

    virtual typename size_type size() const = 0;
};

// Concrete
template <typename T>
class MyVector final : private Container<MyVector<T>> {
public:
    using size_type = typename ContainerTraits<MyVector>::size_type;

    size_type size() const override { return m_data.size(); }

private:
    std::vector<T> m_data;
};

template <typename T>
struct ContainerTraits<MyVector<T>>
{
    using size_type = typename std::vector<T>::size_type;
};
,

我在想...您如何将类型名称传递给类? 作为模板参数!

因此您可以执行以下操作:

#include <vector>

// interface
template <
    /*typename container_type,// not required in this example */
    typename size_type
>
class Container {
public:
    virtual ~Container() = default;

    virtual size_type size() const = 0;
};

template <
    typename value_type,typename size_type = typename std::vector<value_type>::size_type
>
class MyVector final :
    public Container<
        /*MyVector<T>,*/
        size_type
    >
{
public:
    size_type size() const
    {
        return m_data.size();
    }

private:
    std::vector<value_type> m_data;
};

int main()
{
    MyVector<double> v;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。