重复调用 f(T&& t) 形式的函数而不使用 std::move(t) ?

Call functions in the form f(T&& t) repeatedly without using std::move(t) again?

本文关键字:std move 调用 函数      更新时间:2023-10-16
#include <iostream>
#include <cstdlib>
#include "A.h"
void second(const A& a)
{
    std::cout << "void second(const A& a)." << std::endl;
}
void second(A&& a)
{
    std::cout << "void second(A&& a)." << std::endl;
}
void first(const A& a)
{
    std::cout << "void first(const A& a)." << std::endl;
    second(a);
}
void first(A&& a)
{
    std::cout << "void first(A&& a)." << std::endl;
    second(a); //Make this call void second(A&& a) without using std::move(a) again?
}
int main()
{
    std::cout << "int main()." << std::endl;
    A a;
    first(std::move(a));
    std::cin.sync();
    std::cin.get();
    return EXIT_SUCCESS;
}
second(a);

它不能调用second(A&&),因为a是左值(因为它有一个名称)。

调用second(A&&)需要一个右值。因此,您需要将a转换为右值,为此您必须使用move或进行手动显式转换:

second(std::move(a));        //invokes second(A&&)
second(static_cast<A&&>(a)); //invokes second(A&&)

希望对你有帮助。

您是否发现为每个函数编写右值引用重载的过程很乏味,正在寻找一种方法来避免这种乏味?考虑将你的重载压缩成一个函数,该函数按值获取参数,然后将它们移动到需要的地方。

所以,换句话说,这两个函数…

void foo(X const& x) {
    bar(x);
}
void foo(X&& x) {
    bar(std::move(x));
}

…变成这个函数

void foo(X x) {
    bar(std::move(x));
}

对于每一个额外的参数,节省(在类型和可维护性方面)会成倍增加。它有时需要额外的移动,但从不需要额外的复制(当然,除非没有move构造函数)。

函数内部

void first(A&& a)

参数a是一个命名值,因此是左值。

你真的不希望它在第一次函数调用时被移走,因为如果你想在函数中多次使用a,这会造成很多麻烦。考虑

void first(A&& a)
{
    second(a);
    third(a);
    fourth(a);
}

您不希望调用second将值从a移开。