前进或移动或不移动;如何确定在类使用的上下文中哪个是首选?

Fra*_*ler 3 c++ std move-semantics perfect-forwarding c++17

class Test {
public:
    typedef std::set<std::pair<double, double>> DataSet;

    explicit Test(const DataSet&& d) {
        for (auto &itr : d) {
            std::cout << "value1 = " << itr.first << '\n';
            std::cout << "value2 = " << itr.second << '\n';
        }
    }

};

int main() {
    //using namespace util;
    try {
        // Forwarding
        Test obj( std::forward<Test::DataSet>(
            { 
              { 10.0, 20.0 },
              { 30.0, 40.0 },
              { 50.0, 60.0 }
            }
        ));

        std::cout << '\n';

        // Move
        Test obj2(std::move(Test::DataSet(
            {
              { 10.0, 20.0 },
              { 30.0, 40.0 },
              { 50.0, 60.0 }
            }
           )
        ));

    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

wal*_*nut 7

两者都不。

Test::DataSet(/*...*/)已经是可以绑定到右值引用的右值。唯一要做的std::move就是将左值转换为 xvalue(这是一个右值),以便它可以绑定到右值引用,而左值不能。所以std::move是多余的。

std::forward只在其模板参数上做同样的事情。所以它也是多余的(充其量)。

const DataSet&&作为参数没有意义。您想要DataSet&&仅绑定到右值或const DataSet&绑定到右值和左值的 。

如果您想利用传递的引用可能是右值(即从其成员中移动)这一事实,那么您需要对函数进行两次重载。一种采用DataSet&&右值参数调用,另一种采用const DataSet&左值参数调用。

Test您问题中的函数的特定情况下,我看不出从成员中移动或对DataSet状态进行任何其他修改会有什么好处,所以我只会将其const DataSet&作为参数使用,而从不打扰std::moveing 或std::forward专门进入该功能。