c++ - 向标准模板的特化添加新方法(std::vector、std::list...)

标签 c++ templates template-specialization

我想为 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/

相关文章:

c++ - 如何在离开(关闭或失去焦点)窗口之前显示模态确认消息?

c++ - 什么是 C++ 技术规范?

c++ - 如何编写代码在 C++ 中进行条件模板实例化

c++ - 重新声明类名 class-key

返回类型的 C++11 方法模板特化

c++ - CMake:生成单个头文件

c++ - 永远不会在 gmock 中调用 C 字符串

java - playFramework 中 Scala View 模板的转换和实例

c++ - 为什么匹配模板类上的部分类模板特化与没有模板匹配的另一个部分特化不明确?

c++ - 如何使这个带有可变参数的模板特化成为类的 friend ?