[英]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.