2011-05-24 11 views
13

Un par de preguntas sobre boost::swap. Por favor, consulte el siguiente código, que es básicamente un método de cortar y pegar de boost/swap.hpp. Me refiero a la versión de la biblioteca 1.43.0.Pregunta sobre boost :: swap

namespace boost_swap_impl 
    { 
     template<class T> 
     void swap_impl(T& left, T& right) 
     { 
     using namespace std;//use std::swap if argument dependent lookup fails 
     swap(left,right); 
     } 

    template<class T, std::size_t N> 
    void swap_impl(T (& left)[N], T (& right)[N]) 
    { 
    for (std::size_t i = 0; i < N; ++i) 
    { 
     ::boost_swap_impl::swap_impl(left[i], right[i]); 
    } 
    } 
} 

namespace boost 
{ 
    template<class T1, class T2> 
    void swap(T1& left, T2& right) 
    { 
    ::boost_swap_impl::swap_impl(left, right); 
    } 
} 
  1. ¿Por qué se boost::swap declarados como template <typename T1, typename T2> cuando en el resto del código que es todo tratando con el mismo tipo?
  2. Si defino mi propia función global void swap(T&, T&) Veo que es la función global que se llama desde swap_impl(T& left, T& right). ¿No es esto un conflicto y, por lo tanto, una condición de error ya que swap_impl también usa namespace std que tiene swap definido?

Respuesta

19
  1. Esto hace que sea menos especializados que std::swap por lo que no se deje errores sobrecarga de ambigüedad cuando ambos std::swap y boost::swap son de alcance (std::swap tendrá preferencia).
  2. No, no son las plantillas siempre tienen prioridad sobre las plantillas durante la resolución de sobrecarga, por lo que una plantilla no espacio de nombres con ámbito de swap tendrá preferencia sobre ambas boost::swap y std::swap (al igual que una plantilla de espacio de nombres con ámbito de swap sobrecargado por un UDT – pensar parcialmente -especializado, pero en realidad no ...). Tenga en cuenta que a diferencia de std::swap, boost::swap está escrito explícitamente para aprovechar ADL.

Esto es lo que el estándar de C++ 03 tiene que decir con respecto a los dos puntos – [over.match.best] (§13.3.3/1):

Definir ICS i (F) como sigue:

  • si F es una función miembro estático, ICS (F) se define de tal manera que ICS (F) no es ni mejor ni peor que ICS (G) para cualquier función G, y, simétricamente, ICS (G) no es ni mejor ni peor que ICS (F); de lo contrario,
  • let ICS i (F) indican la secuencia de conversión implícita que convierte el argumento -ésimo i de la lista para el tipo del parámetro -ésimo i de la función viable F. 13.3.3.1 define las secuencias de conversión implícitas y 13.3.3.2 define lo que significa que una secuencia de conversión implícita sea una mejor secuencia de conversión o una secuencia de conversión peor que otra.

Teniendo en cuenta estas definiciones, una función viable F1 se define para ser un mejor función que la otra función viable F2 si para todos los argumentos i, ICS i (F1) no es una secuencia de conversión peor que ICS i (F2), y luego

  • por alguna argumento j, ICS j (F1) es una secuencia de conversión mejor que ICS j (F2), o, si no que,
  • F1 es una función no-plantilla y F2 es una plantilla especialización función, o, si no que,
  • F1 y F2 son itinerarios plantilla de función, y la plantilla de función para F1 es más especializado que el molde para F2 de acuerdo con las reglas de ordenación parciales descritas en 14.5.5.2, o, si no que,
  • el contexto es una inicialización por conversión definida por el usuario (ver 8.5, 13.3.1.5 y 1) 3.3.1.6) y la secuencia de conversión estándar del tipo de devolución F1 al tipo de destino (es decir, el tipo de entidad que se inicializa) es una secuencia de conversión mejor que la secuencia de conversión estándar del tipo de devolución F2 al tipo de destino .
+0

@jam: +1. ¿Podría indicarme la sección estándar de referencia de C++ que habla sobre la precedencia de la no plantilla sobre el código de la plantilla? – Fanatic23

+0

@ Fanatic23: Respuesta editada con cita estándar. – ildjarn

+0

@ildjarn: me temo que su nota es [bajo contención] (http://stackoverflow.com/questions/9170247/does-c11-change-the-behavior-of-explicitly-calling-stdswap-to-ensure- adl-loc). Pensé que también era el caso, pero quizás no. – GManNickG