STLifying C++类

sha*_*tor 5 c++ stl class-design

我正在尝试编写一个包含几个std :: vectors作为数据成员的类,并提供了一个vector的接口子集来访问它们:

class Mesh
{
public:
private:
  std::vector<Vector3> positions;
  std::vector<Vector3> normals;
  // Several other members along the same lines
};
Run Code Online (Sandbox Code Playgroud)

你可以用网格做的主要事情是添加位置,法线和其他东西.为了允许类似STL的方式访问Mesh(从数组,其他容器等添加),我很想要添加这样的方法:

public:
  template<class InIter>
  void AddNormals(InIter first, InIter last);
Run Code Online (Sandbox Code Playgroud)

问题是,根据我对模板的理解,这些方法必须在头文件中定义(似乎有意义;没有具体的迭代器类型,编译器不知道如何生成目标代码用于明显的实现方法).

  1. 这实际上是个问题吗?我的直觉反应是不要在头文件中粘贴大量的代码,但我的C++有点生疏,玩具示例之外的STL经验不多,而且我不确定"可接受的"C++编码实践是什么.

  2. 是否有更好的方法来公开此功能,同时保留类似STL的通用编程风格?一种方式是这样的:

(结束名单)

class RestrictedVector<T>
{
public:
  RestrictedVector(std::vector<T> wrapped)
    : wrapped(wrapped) {}

  template <class InIter>
  void Add(InIter first, InIter last)
  {
    std::copy(first, last, std::back_insert_iterator(wrapped));
  }

private:
  std::vector<T> wrapped;
};
Run Code Online (Sandbox Code Playgroud)

然后在Mesh上公开这些实例,但是这开始有点过度工程:P非常感谢任何建议!

Ste*_*sop 5

这些方法必须在头文件中定义

他们在被定义一个头文件,所以,如果他们使用,那么他们在翻译单元,其中模板函数实例化提供.如果您担心头文件中的模板太多,减慢使用Mesh但实际上不使用该模板函数的转换单元的编译,那么您可以将实现移动到单独的头文件中.使客户的生活稍微复杂一些,决定是否包含"全脂"类头,但实际上并不困难.

或者,对于此特定示例,您可以为Mesh定义输出迭代器,其附加Normals.那么具有任意迭代器的客户端可以:

std::copy(first, last, mymesh.normalAdder());
Run Code Online (Sandbox Code Playgroud)

他们需要的唯一标题是模板代码<algorithm>,它们很可能已经存在.

为了自己做,返回的对象normalAdder()需要重载,operator++()并且operator*()它本身需要返回一个实现的代理对象(通常*this)operator=(const &Vector3).这附加到法线向量.但所有这些都是非模板代码,并且可以在.cpp文件中实现.

再次在这个例子中,normalAdder()可以只返回std::back_inserter(this.normals);一个模板<iterator>.

至于你是否需要担心它 - 我认为当编译时间向天空时,它更频繁地由于不必要的依赖性而不是由于标题中的少量模板代码.一些大型项目似乎需要采取严厉的措施,但就我个人而言,我还没有处理过大约100个左右的文件.