Шаблон со статическими функциями против объекта с нестатическими функциями в перегруженном операторе - PullRequest
1 голос
/ 03 декабря 2009

Какой подход лучше и почему?

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 будет оптимизирован "прочь" ...

Спасибо!

Ответы [ 5 ]

3 голосов
/ 03 декабря 2009

Обычно речь идет не о производительности во время выполнения, а о удобочитаемости. Предыдущая версия сообщает потенциальному сопровождающему, что выполняется некоторая форма инициализации объекта. Последнее делает намерение более ясным и должно (на мой взгляд) быть предпочтительным.

Кстати, вы создали класс черт. Посмотрите , как выполняются черты в стандартной библиотеке (они используют статические функции-члены).

2 голосов
/ 03 декабря 2009

Поскольку assistant по сути является набором свободных функций, я бы использовал статический подход (возможно, даже сделал бы конструктор закрытым). Это дает понять, что assistant не предназначен для установки. Кроме того, и это только дикая догадка, это может привести к немного меньшему потреблению памяти, так как не требуется неявный this -пункт (и не экземпляр класса).

1 голос
/ 03 декабря 2009

Я бы использовал объектный подход - он кажется немного более стандартным и похожим на способ передачи функторов в алгоритмы STL - его также проще расширять, позволяя параметрам, передаваемым в конструктор помощника, влиять на результаты операций и т. д. Разницы нет, но объектный подход, вероятно, будет более гибким в долгосрочной перспективе и более синхронизированным с аналогичными решениями, которые вы найдете в других местах.


Почему объект более гибкий? Одним из примеров является то, что вы можете легко реализовать более сложные операции (например, усреднение в этом примере), которые требуют, чтобы вы хранили временный результат «где-то» и требовали анализа результатов от нескольких вызовов, сохраняя при этом ту же «парадигму» использования. Во-вторых, возможно, вы захотите провести некоторую оптимизацию - скажем, вам нужен временный массив, чтобы что-то делать в этих функциях - зачем выделять его каждый раз или иметь статический класс в вашем классе и оставлять зависание и тратить память, когда вы можете выделить его, когда действительно необходимо повторно использовать несколько элементов, но затем отпустить, когда все операции выполнены и вызывается деструктор объекта.

Использование статических функций не дает никаких преимуществ - и, как видно из вышеизложенного, использование объектов имеет по крайней мере несколько преимуществ, поэтому выбор довольно прост. Imho.

Также семантика вызова может быть практически идентична - Assistant (). Sum (A, B) вместо Assistant :: sum (A, B) - действительно мало причин НЕ использовать объектный подход:)

0 голосов
/ 03 декабря 2009

2-й метод предпочтителен, в этом методе не создается "вспомогательная" переменная strcutre, и он вызывает только необходимую функцию-член. Я думаю, что это немного быстрее, чем 1-й метод.

0 голосов
/ 03 декабря 2009

В первом методе должен быть создан помощник, в то время как второй метод состоит только из вызова функции, поэтому второй метод быстрее.

...