C++ 使用无分配交换是否有明显的缺点?

C++ 使用无分配交换是否有明显的缺点?,c++,C++,我正在实现(出于培训目的)气泡排序模板函数: template<typename iterInput, typename predicate> void BubbleSort(iterInput first1,iterInput last1,predicate func) { bool swapped(false); do { swapped = false; iterInput begin = first1;

我正在实现(出于培训目的)气泡排序模板函数:

template<typename iterInput,
         typename predicate>
void BubbleSort(iterInput first1,iterInput last1,predicate func)
{
    bool swapped(false);
    do
    {
        swapped = false;
        iterInput begin = first1;
        iterInput beginMinus = first1;
        ++begin;
        for (;begin != last1; begin++,beginMinus++)
        {
            if (func(*beginMinus,*begin) )
            {
                std::swap(*beginMinus,*begin);
                swapped = true;
            }
        }
    }
    while(swapped);
}
模板
void BubbleSort(iterInput first1、iterInput last1、谓词func)
{
布尔交换(假);
做
{
交换=假;
iterInput begin=first1;
iterInput BEGIN负数=first1;
++开始;
for(;begin!=last1;begin++,begin++)
{
if(func(*begin减号,*开始))
{
标准::交换(*begin减号,*begin);
交换=真;
}
}
}
while(交换);
}
当我意识到这个函数不适用于没有赋值运算符的类时,比如这个(请原谅我的坏名字):

类不可复制
{
公众:
显式NoCopyable(int值):值uz(值){}
NoCopyable(const NoCopyable&other):value_uz(other.value_u){}
~NoCopyable(){}

bool操作符这可能会让未来的代码维护人员感到困惑。

除此之外,如果一个类没有赋值操作符,那么它的设计者可能不打算对它进行交换。如果他们这样做了,他们可能也禁用了复制构造,所以新的交换函数仍然无法工作

至于你所说的标准库容器不需要赋值,只要你不想对它们做任何有用的事情,这是真的。这段代码是为你编译的吗

#include <vector>
using namespace std;

struct A {
    private:
        void operator=( const A &);
};

int main() {
    vector <A> v;
    v.push_back( A() );
    v[0] = A();     // assignment needed here
}
#包括
使用名称空间std;
结构A{
私人:
void运算符=(常量A&);
};
int main(){
向量v;
v、 向后推(A());
v[0]=A();//此处需要赋值
}

我想不会的。

你需要一个复制操作符而不是赋值操作符,但这两个操作符非常相似,至少在典型的情况下,你可以同时拥有它们,或者两者都没有。瞧,我认为这通常不会有多大效果


我将它与xor交换技巧一起分类:有趣,但通常没有用处。

不同的是,当赋值运算符失败时,仍然有相同数量的对象


如果您销毁了一个对象,但未能创建新对象,则一个对象将丢失!如果它是容器的一部分,则容器的状态可能也无效。

很少需要显式析构函数调用…看起来很不确定,为什么您在交换中使用两种不同的类型?如果它们在使用地址的一个对象的放置构造函数时不同另一个的ss无论如何都会非常糟糕…@好的一点,它应该只是一个模板parameter@NeilButterworth如果对象的复制构造函数被禁用,那么该对象将无法与stl容器一起使用,因此没有太多的内容可供排序。@Alessandro那么您正在处理的对象是无法赋值但可以复制的?这些是根据我的经验,这很少见。你的问题是关于swap()的.@Alessandro Teruzzi标准容器要求其包含的对象无论如何都是可赋值的,因此我同意Neil的观点。@Neil Butterworth我认为它们没有你想象的那么罕见。事实上,stl容器不需要赋值运算符,通常用于模板函数(和类)更少的要求意味着更大的灵活性。我对我提供的这个版本的swap感到不舒服,Bo Persson给了我原因。@Mark B哪个标准容器需要赋值运算符?std中的某些函数需要赋值,但容器本身不需要。
template<typename T1,
         typename T2>
void noAssignmentSwap(T1& t1,T2& t2)
{
    T1 temp(t1);
    t1.~T1();
    new (&t1) T1(t2);
    t2.~T2();
    new (&t2) T2(temp);
}
#include <vector>
using namespace std;

struct A {
    private:
        void operator=( const A &);
};

int main() {
    vector <A> v;
    v.push_back( A() );
    v[0] = A();     // assignment needed here
}