Por que usar std :: forward nos conceitos?
Eu estava lendo opágina cppreference em Restrições e notei este exemplo:
// 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));
};
Estou confuso por que eles estão usandostd::forward
. Alguma tentativa de suportar tipos de referência nos parâmetros do modelo? Não queremos ligarswap
com lvalues, e oforward
expressões sejam rvalues quandoT
eU
são tipos escalares (sem referência)?
Por exemplo, eu esperaria que este programa falhasse, dada a suaSwappable
implementação:
#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);
}
Infelizmente o g ++ 7.1.0 me dá umaerro interno do compilador, o que não lança muita luz sobre isso.
Aqui ambosT
eU
deveria estarMyType
estd::forward<T>(t)
deve retornarMyType&&
, que não pode ser passado para o meuswap
função.
Esta implementação deSwappable
errado? Perdi alguma coisa?