具有静态函数的模板与重载运算符中具有非静态函数的对象

发布于 2024-08-13 17:52:19 字数 733 浏览 3 评论 0原文

哪种方法更好,为什么?

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 都会“远离”优化...

谢谢!

Which approach is the better one and why?

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); 
}

Or

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); 
}

To explain the things a bit more: assistant has no state it only provides several utility functions and later I can define template specialization of it to achieve a different behavior for certain types T.

I think for higher optimization levels these two approaches don't lead to different byte codes because anyway the assistant will optimized "away"...

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

眸中客 2024-08-20 17:52:19

这通常不是运行时性能的问题,而是可读性的问题。前一个版本向潜在的维护者传达某种形式的对象初始化已执行的信息。后者使意图更加清晰,并且(在我看来)应该是首选。

顺便说一句,您创建的基本上是一个特征类。看看如何在标准库中完成特征(它们使用静态成员功能)。

It is usually not a question of run-time performance, but one of readability. The former version communicates to a potential maintainer that some form of object initialization is performed. The latter makes the intent much clearer and should be (in my opinion) preferred.

By the way, what you've created is basically a traits class. Take a look at how traits are done in the standard library (they use static member functions).

〆一缕阳光ご 2024-08-20 17:52:19

由于 assistant 本质上是自由函数的集合,因此我会采用静态方法(甚至可能将构造函数设为私有)。这清楚地表明 assistant 并不是为了被任命。另外,这只是一个大胆的猜测,这可能会导致内存消耗稍微减少,因为不需要隐式 this 指针(也不需要该类的实例)。

Since assistant is essentially a collection of free functions, I would go with the static approach (maybe even make the constructor private). This makes clear that assistant is not intended to be instatiated. Also, and this is only a wild guess, this may result in slightly less memory consumption, since no implicit this-pointer (and no instance of the class) is needed.

第七度阳光i 2024-08-20 17:52:19

我会使用对象方法 - 它似乎更标准一点,类似于将函子传递给 STL 算法的方式 - 通过允许将参数传递给助手的构造函数来影响操作等的结果,它也更容易扩展。没有什么区别,但从长远来看,对象方法可能会更加灵活,并且与您在其他地方找到的类似解决方案更加同步。


为什么物体更灵活?一个例子是,您可以轻松实现更复杂的操作(例如本例中的平均值),这些操作要求您将临时结果存储在“某处”,并需要分析几次调用的结果,同时仍然保持相同的使用“范式”。其次,您可能想要做一些优化 - 假设您需要一个临时数组来在这些函数中执行某些操作 - 为什么每次都分配它或将其静态化在您的类中并在可以分配它时留下挂起并浪费内存确实需要,重用许多元素,但当所有操作完成并调用对象的析构函数时释放。

使用静态函数没有任何优势 - 正如上面所看到的,使用对象至少有一些优势,因此选择相当简单。

此外,调用语义实际上可以是相同的 - Assistant().sum( A, B ) 而不是 Assistant::sum( A, B ) - 没有什么理由不使用对象方法:)

I'd use the object approach - it seems a bit more standard and similar to the way you pass functors to STL algorithms - it's also easier to extend by allowing parameters passed to the constructor of the assistant to influence the results of the operations etc. There's no difference but the object approach will probably be more flexible long term and more in sync with similar solutions you'll find elsewhere.


Why an object is more flexible? One example is that you can easily implement more complex operations (like average in this example) that require you to store the temporary result "somewhere" and require analyzing results from a couple invocations while still keeping the same "paradigm" of usage. Second might be you'd want to do some optimization - say you need a temporary array to do something in those functions - why allocate it each time or have it static in your class and leave hanging and waste memory when you can allocate it when it's really needed, re-use on a number of elements but then release when all operations are done and the destructor of the object is called.

There's no advantage to using static functions - and as seen above there are at least a few advantages to using objects so the choice is rather simple imho.

Also the calling semantics can be practically identical - Assistant().sum( A, B ) instead of Assistant::sum( A, B ) - there's really little reason to NOT use an object approach :)

撞了怀 2024-08-20 17:52:19

第一种方法需要创建助手,而第二种方法仅包含函数调用,因此第二种方法更快。

In the first method an assistant has to be created while the second method consists of just the function call, thus the second method is faster.

凡尘雨 2024-08-20 17:52:19

第二种方法是首选,在这种方法中,没有创建 strcutre“辅助”变量,它只调用所需的成员函数。我认为它的执行速度比第一种方法快一点。

2nd method is preferred, in this method, there is no strcutre "assistent" variable created and it is calling only required member function. I think it is little bit faster in execution than 1st method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文