C++11 最佳参数传递

标签 c++ c++11 parameter-passing rvalue-reference

考虑这些类:

#include <iostream>
#include <string>

class A
{
    std::string test;
public:
    A (std::string t) : test(std::move(t)) {}
    A (const A & other) { *this = other; }
    A (A && other) { *this = std::move(other); }

    A & operator = (const A & other)
    {
        std::cerr<<"copying A"<<std::endl;
        test = other.test;
        return *this;
    }

    A & operator = (A && other)
    {
        std::cerr<<"move A"<<std::endl;
        test = other.test;
        return *this;
    }
};

class B
{
    A a;
public:   
    B (A && a) : a(std::move(a)) {}
    B (A const & a) : a(a) {}
};

在创建 B 时,我始终为 A 提供最佳前向路径,右值移动一次或左值复制一次。

是否有可能用一个构造函数实现相同的结果?在这种情况下这不是一个大问题,但是多个参数呢?我需要参数列表中所有可能出现的左值和右值的组合。

这不仅限于构造函数,也适用于函数参数(例如 setter)。

注意:本题严格针对class BA 类 的存在只是为了可视化复制/移动调用是如何执行的。

最佳答案

“按值(value)”方法是一种选择。它不像您所拥有的那样最佳,但只需要一个重载:

class B
{
    A a;
public:   
    B (A _a) : a(move(_a)) {}
};

成本是左值和 xvalue 的 1 次额外移动构造,但这对于纯右值(1 次移动)仍然是最佳的。 “xvalue”是已使用 std::move 转换为右值的左值。

你也可以试试“完美转发”的方案:

class B
{
    A a;
public:   
    template <class T,
              class = typename std::enable_if
              <
                 std::is_constructible<A, T>::value
              >::type>
    B (T&& _a) : a(std::forward<T>(_a)) {}
};

这将使您回到最佳数量的复制/移动结构。但是您应该限制模板构造函数,使其不过分通用。您可能更喜欢使用 is_convertible 而不是 is_constructible ,就像我在上面所做的那样。这也是一个单一的构造函数解决方案,但是随着您添加参数,您的约束会变得越来越复杂。

注意:上述约束之所以必要,是因为没有 B 的客户端当他们查询 std::is_constructible<B, their_type>::value 时会得到错误的答案.如果对 B 没有适当的约束,它将错误地回答 true .

我要说的是,这些解决方案中没有一个总是比其他解决方案更好。这里需要进行工程权衡。

关于C++11 最佳参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10472179/

相关文章:

postgresql - 在 IN() 中使用多值参数

java - "\n","\t"如何分别加新行和制表符?

c++ - 如何在 GCC 4.5 中使用 C++0x 原始字符串?

c++ 删除 move 赋值运算符编译问题

c++ - 按通用引用返回

java - 如何给jvm设置默认参数?

C++有什么方法可以在数字的开头添加小数点?

c++ - 如何检查 GLFW 窗口是否正在运行?

c++ - 了解嵌套结构

c++ - 可以将 &my_boost_array_variable[2] 传递给期望 void* 的 C 函数吗?