繁体   English   中英

如何从子类中提取嵌套类型并在抽象父类中的虚函数的函数签名中使用它?

[英]How can I extract a nested type from a child class and use it in the function signature of a virtual function in the abstract parent class?

我经常不得不在 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()的抽象函数定义中引用任何子类的size_type


编辑

应用 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”的成员

从对相关问题的回答中,我发现了一些有效的方法。 这有点难看,因为它需要我为我想要实现的每个容器定义一个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;
}

暂无
暂无

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

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