que estaba poniendo en práctica (con fines de formación) una burbuja función Clasificar plantilla:¿Hay algún inconveniente obvio para usar un intercambio sin asignación?
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);
}
Cuando me he dado cuenta de que esta función no funcionará para la clase con ningún operador de asignación, como éste (perdóname por la mala fama):
class NoCopyable
{
public:
explicit NoCopyable(int value) : value_(value) {}
NoCopyable(const NoCopyable& other) : value_(other.value_) {}
~NoCopyable() {}
bool operator<(const NoCopyable& other) { return value_ < other.value_; }
void setValue(int value) { value_ = value; }
std::ostream& print(std::ostream& os) const { return os << value_; }
private:
NoCopyable& operator=(const NoCopyable& other);
int value_;
};
std::ostream& operator<<(std::ostream& os, const NoCopyable& obj)
{
return obj.print(os);
}
struct PrintNoCopyable
{
void operator()(const NoCopyable& noCopyable) { std::cout << noCopyable << '\n'; }
};
el compilador plantea este error error 1 error C2248: 'NoCopyable operador :: =': no se puede miembro privado de acceso declarado en la clase 'NoCopyable'
lo tanto, he modificar ligeramente el código utilizando en lugar del std :: swap de funcionar mi versión de la función de intercambio, aquí está el código:
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);
}
El código se compila y da el resultado correcto. Sin embargo, no estoy del todo seguro, recuerdo un artículo de Sutter que sugiere que evites jugar con los objetos de por vida. El artículo te advierte jugando con fuego sin darte ninguna razón real. Puedo ver un problema en la seguridad de excepciones si el constructor de copias de T1 o T2 puede lanzar. Sin embargo, existe el mismo problema en la versión estándar si el operador de asignación puede lanzar.
Aquí la pregunta, ¿puedes ver los posibles inconvenientes en esta versión de intercambio?
Saludos
llamadas de destructor explícito son raramente necesarias ... se ve iffy imho –
¿Por qué utiliza dos tipos diferentes en el intercambio? si son diferentes usando el constructor de colocación para un objeto con la dirección del otro va a ser muy malo ... – 6502
@ punto bueno, debería ser solo un parámetro de plantilla –