【问题标题】:std::move in constructor initializer list in class template类模板中的构造函数初始化列表中的 std::move
【发布时间】:2013-06-06 16:55:26
【问题描述】:

我有一个这样的模板:

template<typename T>
struct foo {
  T m_t;
  foo(T t) : m_t(t) {}
};

问题是我想同时支持 T 的小型/常规类型和 huge 类型(如矩阵)。你推荐我这样写构造函数初始化列表吗

foo (T t) : m_t(std::move(t)) {}

并要求T 类型始终支持移动构造,即使对于较小的类型也是如此?有更好的方法吗?

【问题讨论】:

    标签: c++ c++11 move-semantics


    【解决方案1】:

    并要求类型 T 始终支持移动构造,即使对于较小的类型?

    任何可复制构造的类型也是可移动构造的。在这些情况下移动只需调用复制构造函数。因此,没有理由使用m_t(std::move(t))

    另一种方法是使用引用:

    foo (T const& t) : m_t(t) {}
    foo (T&& t) : m_t(std::move(t)) {}
    

    这样做的好处是只涉及一个结构而不是两个。

    【讨论】:

    • 你的参考方式比我的好吗?如果 T 不可移动构造它是(或应该)暗示 T 是小/正常(不是大),不是吗?在这种情况下,您认为参考能给我带来任何可衡量的性能优势吗?
    • @7cows 当 T 具有昂贵的复制构造函数并且没有移动构造函数时,它可以提供可衡量的性能优势,这在 C++03 库中很常见。不过我通常更喜欢你的方式。
    【解决方案2】:

    是的,在这种情况下使用该招式没有任何劣势。所有可复制的对象都是自动可移动的,所以没关系。事实上,有些人建议尽可能移动变量,甚至是整数。

    作为替代方案,您可以考虑使用完美转发,如this answer 中所述:

    template <typename T2>
    foo(T2&& t) : m_t(std::forward<T2>(t)) {}
    

    如果您知道T 定义了一个快速移动构造函数,那应该没关系。否则,建议提供构造函数foo(const T&amp;),以避免不必要的复制。

    完美转发只是实现这一目标的一种技术。 Pubby 写出构造函数foo(const T&amp;)foo(T&amp;&amp;) 的解决方案当然也可以。结果都是一样的,主要是风格问题。

    您还询问了小整数类型。理论上,通过引用传递它们比复制它们要慢,但无论如何编译器应该能够将其优化为副本。我不认为这会有所作为。

    因此,最好针对T 可能很大且不提供快速移动构造函数的最坏情况进行优化。通过引用传递最适合这种情况,一般来说也不应该是一个糟糕的选择。

    【讨论】:

    • 完美转发的问题在于它会接受T的构造函数接受的一切
    • @Pubby 好点。这可能是积极的或消极的,取决于上下文。如果需要对转换进行更多控制,则可以另外将两个 foo 构造函数声明为 explicit
    • @Pubby,可以通过enable_ifis_same 检查来控制。诚然,当你写完这篇文章时,你可能正在查看与显式实现两个构造函数相同数量的行...
    【解决方案3】:

    按值传递的优点是只有一个构造函数(没有模板),但与上述替代方法相比,代价是增加了一个移动构造。

    但是,Pubby 给出的按值传递和非模板解决方案还有一个尚未提及的缺点:如果复制构造函数定义为 T(T&amp;);,则移动将不起作用(请注意对非模板的引用常量)。 Rvalue-references 可以绑定到 lvalue-references-to-const,但不能绑定到 lvalue-references-to-non-const,因此编译器不能调用复制构造函数。

    要解决此问题,您只需在 Pubby 的解决方案中添加第三个重载 foo (T &amp; t) : m_t(t) {}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 2016-02-16
      • 2018-01-13
      • 1970-01-01
      相关资源
      最近更新 更多