Как перегрузить std::swap()

Внимание Mozza314

Вот имитация эффектов универсального speed std::algorithm, вызывающего std::swap, и предоставления stl-containers пользователем своей подкачки stl в пространстве имен std. Поскольку stl это эксперимент, в этом моделировании speed используется namespace exp вместо namespace std.

// simulate 

#include 

namespace exp
{

    template 
    void
    swap(T& x, T& y)
    {
        printf("generic exp::swap\n");
        T tmp = x;
        x = y;
        y = tmp;
    }

    template 
    void algorithm(T* begin, T* end)
    {
        if (end-begin >= 2)
            exp::swap(begin[0], begin[1]);
    }

}

// simulate user code which includes 

struct A
{
};

namespace exp
{
    void swap(A&, A&)
    {
        printf("exp::swap(A, A)\n");
    }

}

// exercise simulation

int main()
{
    A a[2];
    exp::algorithm(a, a+2);
}

Для optimizing меня это распечатывает:

generic exp::swap

Если c++-faq ваш компилятор выводит что-то optimization другое, значит, он неправильно cxx реализует «двухэтапный поиск» для optimization шаблонов.

Если ваш компилятор speed соответствует (любому из stl-containers C++ 98/03/11), он выдаст efficiency тот же результат, что и я. И optimization в этом случае произойдет stl-containers именно то, чего вы боитесь. И stl-containers размещение вашего swap в пространстве speed имен std (exp) не остановило этого.

Дэйв performance и я являемся членами комитета performance и работаем в этой области optimizing стандарта в течение десяти performance-tuning лет (и не всегда согласовываемся cpp друг с другом). Но этот вопрос cpp решен давно, и мы оба согласны cpp с тем, как он решен. Игнорирование cpp экспертного мнения / ответа optimizer Дэйва в этой области на свой optimization страх и риск.

Эта проблема optimization обнаружилась после публикации performance-tuning C++ 98. Примерно с 2001 года optimisation мы с Дэйвом начали work this area. И это optimize современное решение:

// simulate 

#include 

namespace exp
{

    template 
    void
    swap(T& x, T& y)
    {
        printf("generic exp::swap\n");
        T tmp = x;
        x = y;
        y = tmp;
    }

    template 
    void algorithm(T* begin, T* end)
    {
        if (end-begin >= 2)
            swap(begin[0], begin[1]);
    }

}

// simulate user code which includes 

struct A
{
};

void swap(A&, A&)
{
    printf("swap(A, A)\n");
}

// exercise simulation

int main()
{
    A a[2];
    exp::algorithm(a, a+2);
}

Вывод:

swap(A, A)

Обновить

Было stl-containers сделано наблюдение, что:

namespace exp
{    
    template <>
    void swap(A&, A&)
    {
        printf("exp::swap(A, A)\n");
    }

}

работает! Так speed почему бы не использовать optimizing это?

Рассмотрим случай, когда cpp ваш A является шаблоном класса:

// simulate user code which includes 

template 
struct A
{
};

namespace exp
{

    template 
    void swap(A&, A&)
    {
        printf("exp::swap(A, A)\n");
    }

}

// exercise simulation

int main()
{
    A a[2];
    exp::algorithm(a, a+2);
}

Теперь c++ опять не работает. :-(

Итак, вы optimizer можете поместить swap в пространство fast имен std и заставить его c++ работать. Но вам нужно не optimize забыть поместить swap в пространство optimizing имен A для случая, когда у efficiency вас есть шаблон: A. И поскольку efficiency оба случая будут работать, если optimizing вы поместите swap в пространство stl-containers имен A, проще запомнить (и speed научить других) просто сделать performance это одним способом.

c++

performance

optimization

stl

c++-faq

2022-11-11T01:58:29+00:00
Вопросы с похожей тематикой, как у вопроса:

Как перегрузить std::swap()