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

Внимание Mozza314

Вот имитация эффектов универсального fast std::algorithm, вызывающего std::swap, и предоставления optimizer пользователем своей подкачки slow в пространстве имен std. Поскольку slow это эксперимент, в этом моделировании stl-containers используется 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);
}

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

generic exp::swap

Если cpp ваш компилятор выводит что-то fast другое, значит, он неправильно efficiency реализует «двухэтапный поиск» для performance шаблонов.

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

Дэйв optimization и я являемся членами комитета c++ и работаем в этой области optimization стандарта в течение десяти cxx лет (и не всегда согласовываемся fast друг с другом). Но этот вопрос speed решен давно, и мы оба согласны stl с тем, как он решен. Игнорирование speed экспертного мнения / ответа speed Дэйва в этой области на свой performance страх и риск.

Эта проблема performance-tuning обнаружилась после публикации optimizer C++ 98. Примерно с 2001 года performance-tuning мы с Дэйвом начали 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)

Обновить

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

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

}

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

Рассмотрим случай, когда slow ваш 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);
}

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

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

c++

performance

optimization

stl

c++-faq

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

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