是否前进或移动;如何确定在 class 的用法中哪个是首选?

To forward or move or not; how to determine which is preferred within the context of a class's usage?

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;
}

都没有。

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

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

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

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

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

[根据评论编辑的代码示例]
ISO 核心指南中 advice 的有用信息。这表明您应该更喜欢 (const T&),但如果您真的需要速度,请专门添加一个 (T&&)。这样你就可以将小集合作为(L-Value)

const auto data = Test::DataSet{ 
          { 10.0, 20.0 },
          { 30.0, 40.0 },
          { 50.0, 60.0 }};
Test obj( data );

或(R 值)

Test obj( Test::DataSet{ 
          { 10.0, 20.0 },
          { 30.0, 40.0 },
          { 50.0, 60.0 },
        });

添加额外的移动使第二种调用更有效,但建议仅在需要时才使用这种类型的优化。您应该避免一个构造函数与另一个构造函数具有不同的语义,避免这种情况的最简单方法是只有一个构造函数。

就个人而言,即使经过 20 多年的 C++ 编程,我发现 link 中的 table 非常有用,我将其打印出来并贴在我的显示器上。