Используйте макрос для специализации std :: swap - PullRequest
2 голосов
/ 18 июля 2009

Итак, у меня есть макрос.

// swap_specialize.hpp
#include <algorithm>

#ifndef STD_SWAP_SPECIALIZE
#define STD_SWAP_SPECIALIZE( CLASSNAME )            \
    namespace std {                                 \
    template<> inline                               \
    void swap( CLASSNAME & lhs, CLASSNAME & rhs )   \
    { lhs.swap(rhs); } }
#endif

Итак, у меня есть класс

// c.hpp
#include <vector>
#include "swap_specialize.hpp"
class C
{
    public:
        C();

        void swap(C& rhs)
        {
            data_.swap(rhs.data_);
        }
        C& operator=(C rhs)
        {
            rhs.swap(*this);
            return *this;
        }
    private:
        std::vector<int> data_;
}

STD_SWAP_SPECIALIZE(C)

Соответствует ли использование макроса для специализации std :: swap соглашениям по кодированию?

Ответы [ 3 ]

6 голосов
/ 18 июля 2009

Я бы сказал, что все в порядке, если это увеличивает читабельность.Суди себя.Только мои два цента: специализация std::swap не совсем правильный способ сделать это.Рассмотрим следующую ситуацию:

my_stuff::C c, b;
// ...
swap(c, b);
// ...

Это не найдет std::swap, если вы еще не сделали using std::swap или что-то подобное.Вам лучше объявить свой собственный своп в пространстве имен C:

void swap(C &a, C &b) {
  a.swap(b);
}

Теперь это будет работать и в вышеприведенном случае, потому что поиск в зависимости от аргументов выполняет поиск в пространстве имен класса.Перестановка кода применительно к обычным вещам, для которых тип неизвестен, должна делать это следующим образом:

using std::swap;
swap(a, b);

Независимо от типа, при этом будет использоваться наиболее подходящий своп, и откат к std::swap еслилучше подходит в пространствах имен a.Жесткое кодирование вызова к std::swap будет слишком коротким для типов, которые не специализируются на std::swap, а скорее решат обеспечить свой собственный обмен в своем пространстве имен.

Это очень важно по-другому: представьте себе C это шаблон.Вы не можете специализироваться std::swap в этом случае.Но просто определить собственный своп - это прекрасно.

template<typename T>
void swap(C<T> &a, C<T> &b) {
  a.swap(b);
}

Так же реализован своп для std::string и других классов.

0 голосов
/ 18 июля 2009

Предполагая, что вы собираетесь использовать STD_SWAP_SPECIALIZE() для ряда других классов, это вполне разумно. Ведь гораздо удобнее читать серию

STD_SWAP_SPECIALIZE(Foo)
STD_SWAP_SPECIALIZE(Bar)
STD_SWAP_SPECIALIZE(Baz)

Чем эквивалентный расширенный код. Кроме того, если расширение STD_SWAP_SPECIALIZE было немного больше, то определение макроса дает вам код в одном месте, если его нужно изменить. (Поскольку это определение шаблона довольно мало в вашем примере, это, вероятно, спорный вопрос).

0 голосов
/ 18 июля 2009

Я не вижу, что это покупает тебя сильно. Для не шаблонных классов это экономит вам очень мало строк. А для шаблонных классов, когда вы хотите специализироваться в общем (т.е. для всех T), это просто не будет работать.

...