我想为 std::list<Picture>
创建特化这将为包含 Picture
的列表添加额外的方法, 但我不知道我试过的这种方式是否可行。
我试过:
template <typename _Alloc = std::allocator<Picture>>
class list : protected _List_base<Picture, _Alloc>
{
public:
void draw()
{
// some code
}
};
int main()
{
std::list<Picture> myList;
//adding elements to mylist
mylist.draw();
return 0;
}
编译后报错:
error: ‘class std::__cxx11::list<Picture>’ has no member named ‘draw’
最佳答案
专门化STL类型
您可以专门化 STL 类型,但正如在另一个答案中提到的,它们需要在命名空间 std 中专门化。这意味着您应该这样做:
namespace std {
template <typename _Alloc = std::allocator<Picture>>
class list<Picture, _Alloc> {
/* stuff */
};
}
或者这个:
template<typename _Alloc = std::allocator<Picture>>
class std::list<Picture, _Alloc> {
/* stuff
};
也就是说,不要从 _List_base
继承。该类是 std::list
的一个实现细节,这意味着它是标准库的一个特定实现选择实现 std::list
的一种方式。其他编译器可能没有。
解决您的问题
如果你想要一个具有.draw()
函数的类列表类,你可以继承std::list
:
template<class Drawable>
class DrawableList : public std::list<Drawable>
{
public:
// It's handy to have this to refer to the base
using base_t = std::list<Drawable>;
using base_t::base_t; // Use std::list`s constructor
// Add your draw function
void draw(int x, int y) {
for(Drawable& item : *this) {
item.draw(x, y);
}
}
};
继承std::list
的注意事项
从 std::list
继承有一些注意事项。因为 std::list
不需要动态多态性,这意味着它没有虚拟析构函数(或任何其他虚拟方法)。您基本上只是围绕 std::list
制作一个包装器类。
此外,如果您向 DrawableList
添加任何字段,则在将其复制到 std::list
时,这些字段可能会被截断。这称为对象切片。
DrawableList<Picture> a = /* stuff */;
std::list<Picture> b = a; // This will compile without any issues
DrawableList<Picture> c = b; // Oops; any extra fields you had in a got cut off
或者,只需使用免费的draw
函数:
void draw(std::list<Picture>& pictures, int x, int y) {
for(auto& picture : pictures) {
picture.draw(x, y);
}
}
关于c++ - 向标准模板的特化添加新方法(std::vector、std::list...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57260716/