【问题标题】:Why I should not provide a forward and move versions for my types?为什么我不应该为我的类型提供 forward 和 move 版本?
【发布时间】:2021-04-05 00:50:17
【问题描述】:

我使用过std::swapstd::movestd::forward,但建议不要重载后两个参数,因为它们已经有可以保存任何类型值的参数,例如前向引用。所以我应该完全限定对这两个函数的调用:

std::move(x);
std::forward<T&&>(x);

而且我读到我可以提供我自己的swap 版本,因此我只为标准库添加一个usung 声明,然后调用swap 而不对其进行限定(非限定查找):

using std::swap;// in case my class doesn't provide a swap version

swap(x, y); // where x, y are of class type. so don't use std::swap directly
  • 那么为什么我不应该为我的类型提供std::movestd::forward 的版本呢?

  • 这是否意味着如果我提供版本,则没有任何好处,因为库的版本更像是证明排序功能,而库的版本则要好得多?

【问题讨论】:

  • 您认为提供std::move 的重载会是什么样子?

标签: c++ move swap forward


【解决方案1】:

只有在标准允许的情况下,您才可以提供 std 函数的特化。没有为std::movestd::forward 提供此类权限。这样做会使您的程序格式错误,无需诊断。

std::swap 你应该只在默认实现有效率问题时专门化(而不是重载!)。默认实现基本上是:

void std::swap( T& lhs, T& rhs ) {
  auto tmp = std::move(lhs);
  lhs = std::move(rhs);
  rhs = std::move(tmp);
}

最常见的情况是您的类型需要在“空”时分配内存。更有效的交换可以避免这种分配。

但对于大多数类型来说,这不是问题。

【讨论】:

  • 对于std::swap,我不这么认为,我们正在重载它而不是专门化它。它的特殊化应该看起来像: namespace std{ template void swap(Foo&, Foo&); // 特化不是重载} 如果重载它: void swap(Foo&, Foo&);毕竟它是一个函数模板,所以它的特化必须是完全特化(模板关键字后跟空括号)。
  • @ItachiUchiwa 命名空间 std 中用户编写的重载是不合法的。您的程序格式错误,无需诊断。标准规定您何时可以向命名空间 std 添加特化,并且此类特化可能不会违反保证的标准要求,并且添加 anything else 会使您的程序格式错误,NDR。所以你必须专攻,不要意外超载。当然,重载有时会与某些标准库和某些用途一起使用,这使得它非常阴险。
猜你喜欢
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 2012-10-06
  • 1970-01-01
  • 2012-08-28
  • 1970-01-01
相关资源
最近更新 更多