【问题标题】:In a header file for other programm to use, can I only declare the templates?在其他程序使用的头文件中,我可以只声明模板吗?
【发布时间】:2009-10-07 21:58:01
【问题描述】:

我想知道是否使用模板,在其他线程中我发现由于某些原因必须在头文件中实现模板。 没关系,我的问题是如果其他程序使用它,是否需要源? 从其他线程答案的逻辑来看,似乎即使是其他程序也需要完整的实现,因此编译器可以判断一行是否可以使用模板化函数。

如果是,我想模板对于希望其他人使用他的库的开发人员来说不是一件好事? 如果没有,那么我们很好,将使用模板。

或者至少有什么办法可以节省我的辛苦、花费的时间和其他人的代码?

(我将使用 stl 向量等,但我要求我自己的代码......模板似乎很好,为您节省了很多硬编码的行或宏滥用,但如果其他人可以阅读您的源代码而不是它使几乎没有意义[打开项目很有意义xD])

谢谢, 乔

【问题讨论】:

  • 您可能想提供更多详细信息。 Boost 和 STL 在模板化方面没有问题。模板是一件好事,因为代码可用并且您可以从中学习(更改其他人的库可能不是一个好主意)。除非你有什么要隐藏的。您稍后还提到了一些关于基类的事情,这听起来很奇怪。模板不关心类型是否相关。可能是正常的运行时多态性合适吗?
  • 我需要一个对象工厂,所以模板很适合……但所有其他东西都与多态性有关。我曾经是 C(CircleMUD 有人吗?)程序员并因为我以前工作的公司而跳到 C#,现在我进入 C++ 并且一开始有点困惑,因为我习惯于每天看到的所有 C#...
  • 我认为某些层次结构需要对象工厂(不是模板通常使用的任何东西)。一方面,我认为工厂也可以是多态的。但也应该可以实例化所需的模板并将实现与声明分开。

标签: c++ templates header implementation


【解决方案1】:

如果您希望您的库的用户能够使用您的模板,则他们的源代码需要对这些用户可用。

但是,您有时可以设计模板类,以便大部分逻辑发生在标头中没有完整源代码的非模板类中。

【讨论】:

  • 是的,你是对的,至少对于这个初始设计,我似乎可以将大部分函数设为私有,然后从模板函数中调用它们,我想我会编程更多,看看需要用于更深层次的模板
【解决方案2】:

这取决于您的模板是库接口的一部分还是只是实现的一部分。

如果它们是接口的一部分(即,入口点可能返回特定模板类型的对象),那么是的,您需要将模板定义暴露给外界。

但是,如果模板只是您实现的一部分,那么一旦您构建了您的库,就无需与您的库的使用者共享模板定义。

【讨论】:

  • 嗯,我想基本上在实现上使用它。所以我想这是一个很好的设计,我使用模板的简单性但未经许可不要分享我的项目。但是我想每次我将一个包含文件交给其他软件时,我都必须复制和编辑头文件以不显示源代码对吗?还是有其他解决方法?
  • 如果您的模板不是界面的一部分,您甚至不必向用户提供该标头。如果您确实需要提供模板头文件,那么您需要重构头文件,以便接口头文件不需要实现头文件(如果这不可能,那么模板不是真正的实现,而是一部分界面)。
【解决方案3】:

您可以将模板编写为非模板(通常是非类型安全)代码的包装器。

优点是……

  1. 非模板实现代码的源代码无需分发。
  2. 这是减少模板膨胀的好方法。

明显的缺点是你有额外的抽象层和开销,非类型安全的实现代码显然需要小心。我倾向于在非模板代码中定义一个抽象的“工具”类,专门用于模板包装器。我称它为工具,因为方法主要不是作用于工具状态,而是作用于作为 void* 参数传入的对象。工具类将大多数类型不安全问题封装在几个方法中。该模板还提供了用户实际使用的类型安全包装器,它与不安全代码接口,提供工具实例并进行类型转换等。

例如,如果我正在实现一个树数据结构,大多数树算法将是类型不安全的,并且会将节点和数据项视为 void* 指针(或者可能是 node* 和 data* 指针,其中声明了节点和数据但未定义的结构)。我将有一个抽象的树工具库,其中包含用于节点创建、处理和其他基本操作的纯方法,包装器模板将基本上专门化树工具,提供知道节点和数据项的精确类型的方法实现,并持有该工具的一个实例作为类成员。对用户而言,包装器只是一个类型安全的容器,与其他容器一样。

顺便说一句 - 在实现模板包装器时,请注意 dependent name 问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2023-04-08
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多