J'ai été regarder Scott Meyers parler sur des Références Universelles de le C++ et au-Delà de 2012 de la conférence, et tout prend sens jusqu'à présent. Cependant, un membre de l'auditoire pose une question, à environ 50 minutes en qui je me demandais aussi sur. Meyers dit qu'il ne se soucie pas de la réponse, car elle est non-idiomatiques et serait stupide son esprit, mais je suis toujours intéressé.
Le code présenté est comme suit:
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
Le point étant que lorsque nous prenons une référence rvalue, nous savons que nous avons une rvalue, donc nous devrions std::move
il pour préserver le fait que c'est une rvalue. Lorsque nous prenons une référence universelle (T&&
où T
est déduit de type), nous voulons std::forward
afin de préserver le fait qu'il peut avoir été une lvalue ou une rvalue.
Donc la question est: depuis std::forward
conserve si la valeur passée dans la fonction était soit une lvalue ou une rvalue, et std::move
tout simplement jette son argument à une rvalue, pourrait-on simplement utiliser std::forward
partout? Serait - std::forward
se comportent comme des std::move
dans tous les cas où l'on utiliserait std::move
, ou il y a des différences importantes dans le comportement qui sont manqués par Meyers généralisation?
Je ne dis pas que tout le monde devrait le faire, parce que, comme Meyers dit correctement, il est complètement non-idiomatique, mais est également une utilisation valide de std::move
:
void doWork(Widget&& param) // move
{
// ops and exprs using std::forward<Widget>(param)
}