哪种方法更好,为什么?
template<typename T>
struct assistant {
T sum(const T& x, const T& y) const { ... }
};
template<typename T>
T operator+ (const T& x, const T& y) {
assistant<T> t;
return t.sum(x, y);
}
或者
template<typename T>
struct assistant {
static T sum(const T& x, const T& y) { ... }
};
template<typename T>
T operator+ (const T& x, const T& y) {
return assistant<T>::sum(x, y);
}
更多地解释一下:assistant
没有状态它只提供了几个实用函数,后来我可以定义它的模板特化,以实现某些类型T
的不同行为。
我认为对于更高的优化级别,这两种方法不会导致不同的字节代码,因为无论如何assistant
将优化“远离”......
谢谢!
答案 0 :(得分:3)
通常不是运行时性能问题,而是可读性问题。前一版本与潜在的维护者通信,执行某种形式的对象初始化。后者使意图更清晰,应该(在我看来)是首选。
顺便说一下,你创造的基本上是一个特质类。看一下how traits are done in the standard library(他们使用静态成员函数)。
答案 1 :(得分:2)
由于assistant
本质上是一个自由函数的集合,我会采用静态方法(甚至可能使构造函数变为私有)。这清楚地表明assistant
并非旨在实例化。此外,这只是一个疯狂的猜测,这可能会导致内存消耗略少,因为不需要隐式this
- 指针(并且不需要类的实例)。
答案 2 :(得分:1)
我使用对象方法 - 它看起来更标准,类似于将仿函数传递给STL算法的方式 - 通过允许传递给助手的构造函数的参数来影响结果,也更容易扩展操作等没有区别,但对象方法可能会更长期灵活,并且与您在其他地方找到的类似解决方案更加同步。
为什么对象更灵活?一个例子是,您可以轻松实现更复杂的操作(例如本例中的平均值),这些操作要求您将“临时结果”存储在“某处”,并且需要分析来自几个调用的结果,同时仍保持相同的“范例”使用。第二个可能是你想做一些优化 - 比如说你需要一个临时数组来做这些功能的事情 - 为什么每次都要分配它或者让它在你的类中保持静态,当你可以分配它时留下内存和浪费内存真的需要,重复使用许多元素,但在完成所有操作并调用对象的析构函数后释放。
使用静态函数没有任何优势 - 如上所述,使用对象至少有一些优点,因此选择相当简单。
调用语义也几乎相同--Assistant()。sum(A,B)而不是Assistant :: sum(A,B) - 没有理由不使用对象方法:)
答案 3 :(得分:0)
在第一种方法中,必须创建助手,而第二种方法只包含函数调用,因此第二种方法更快。
答案 4 :(得分:0)
第二种方法是首选,在这种方法中,没有创建strcutre“assistent”变量,它只调用所需的成员函数。我认为它的执行速度比第一种方法快一点。