2

要为类 cls 提供功能,比如“添加”,以下是我决定的类型:

struct add
{
      add sum(add other) { ... }
};

对比

template<typename Add>
Add sum(Add one, Add two) { ... }

应该首选哪种方法,第一种方法比第二种方法有什么优势,反之亦然?

4

4 回答 4

4

应该首选哪种方法,第一种方法比第二种方法有什么优势,反之亦然?

我相信这个问题没有一个简单的答案。我认为这可以归结为泛型与面向对象编程之争。

另见关于 C++ 中面向对象和泛型编程之间的紧张关系

于 2011-04-17T13:32:42.393 回答
2

您的示例之间有两点不同。首先,正如您正确指出的那样,您的第二个示例是使用函数模板。但其次,它使用的是自由函数,而不是成员函数。

为了公平比较,您应该比较:

add sum(add one, add two) { ... }

和:

template<typename Add>
Add sum(Add one, Add two) { ... }

虽然第二种变体可能更有用,但它取决于您将如何编写函数体。它可以用通用的方式编写,并且仍然对add对象执行操作吗?

于 2011-04-17T12:52:55.620 回答
0

第一个对我来说没有意义,或者它太糟糕以至于没有意义,因为你编写一个类只是为了执行一些“操作”。一个类应该在面向对象编程中表示一个对象(或者如果它的类模板,它可以在模板元编程中充当元函数)。

对于操作,对对象进行操作的函数是有意义的。所以第二个是有道理的,但我会将类型参数的名称更改为:

template<typename T>
T sum(const T & one, const T & two) { ... }

毕竟,是什么Add

于 2011-04-17T12:52:23.450 回答
0

何时会做出与类型相关的决定?如果是运行时,那么您必须使用虚拟方法,如果是编译时,那么您可能可以使用模板代替(当然,即使类型在运行时固定,您也可以使用虚拟方法,但这效率较低)。

如果类型在运行时是固定的,您可以使用模板一些技巧来避免告诉您正在使用哪些类型并让编译器找到它们并生成正确的代码。

但是请注意,C++ 不允许对模板函数进行部分特化,只允许对模板类进行部分特化,因此为了获得最大的灵活性,您可能需要将功能包装为模板结构的方法(即使是静态方法也可以)。一旦你有了你的模板类编译时调度机制,你就可以添加模板函数来允许类型推导和简化语法。

于 2011-04-17T13:40:14.037 回答