¿Por qué usar std :: forward en conceptos?
Estaba leyendo elPágina de preferencias sobre restricciones y noté este ejemplo:
// example constraint from the standard library (ranges TS)
template <class T, class U = T>
concept bool Swappable = requires(T t, U u) {
swap(std::forward<T>(t), std::forward<U>(u));
swap(std::forward<U>(u), std::forward<T>(t));
};
Estoy confundido por qué están usandostd::forward
. ¿Algún intento de admitir tipos de referencia en los parámetros de la plantilla? No queremos llamarswap
con valores, y no sería elforward
las expresiones sean valores cuandoT
yU
son tipos escalares (sin referencia)?
Por ejemplo, esperaría que este programa fallara dado suSwappable
implementación:
#include <utility>
// example constraint from the standard library (ranges TS)
template <class T, class U = T>
concept bool Swappable = requires(T t, U u) {
swap(std::forward<T>(t), std::forward<U>(u));
swap(std::forward<U>(u), std::forward<T>(t));
};
class MyType {};
void swap(MyType&, MyType&) {}
void f(Swappable& x) {}
int main()
{
MyType x;
f(x);
}
Lamentablemente, g ++ 7.1.0 me da unerror interno del compilador, que no arroja mucha luz sobre esto.
Aquí los dosT
yU
debiera serMyType
ystd::forward<T>(t)
debería volverMyType&&
, que no se puede pasar a miswap
función.
¿Es esta implementación deSwappable
¿incorrecto? ¿Me he perdido algo?