【问题标题】:Are there any pitfalls in using move() instead of std::move()?使用 move() 而不是 std::move() 有什么陷阱吗?
【发布时间】:2014-05-21 10:57:26
【问题描述】:

在使用新的 C++11 的 std::move() 时,我注意到,由于 ADL,可以只编写 move(),而无需 std:: 命名空间前缀。

使用move() 好吗?有什么陷阱吗?使用std::move()会更好吗?


示例可编译代码如下:

#include <iostream>
#include <utility>
#include <vector>

template <typename T>
void print(const char* const descr, const std::vector<T>& v) {
    std::cout << descr << ": ";
    for (const auto& x : v) {
        std::cout << x << ' ';
    }
    std::cout << std::endl;    
}

int main() {
    std::vector<int> v{11, 22, 33};
    std::vector<int> w = move(v);

    print("v", v);
    print("w", w);
}

【问题讨论】:

  • "move() 看起来比 std::move()" 更干净。此外,如果您的 move() 需要做的不仅仅是 std::move() 并且需要由 ADL 找到,那么您的 move() 已损坏。

标签: c++ c++11 move


【解决方案1】:

如果参数类型也在 std 中,ADL 只会在 std 中查找内容。

如果在另一个正在使用的命名空间中有另一个名为move 的符号,那么编译器将不知道您的意思。现在可能没有,但未来的变化可能会带来一个。

此外,始终使用std:: 可以让人们以后更轻松地阅读您的代码。它清楚地表明它不是您自己定义的或从另一个库中包含的move。如果他们以前没有听说过(相对较新的)std::move,则特别有用。

【讨论】:

  • 使用ADL的全部目的是扩大查找范围,这是一个理想的效果。参考文献整个boost::swap 的想法。我想 move 不需要重新定义,因为它有一个通用的实现。如此之多,它甚至可以是一个关键字。但这是一个非常特殊的情况,一般不能将其视为反对“ADL 启用模式”的情况。
【解决方案2】:

一定要用std::move!如果类型是在 std 命名空间中定义的(由于 ADL),它可以在没有 std:: 的情况下工作仅。它不适用于任何其他类型,如整数类型或使用定义的类型。


例子:

std::vector<int> v = {1,2,3};
std::vector<int> w = move(w); // will work due to ADL
int i1 = 4;
int i2 = move(i1); // ERROR
struct Foo {};
Foo x{};
Foo y = move(x); // ERROR

【讨论】:

  • @Mr.C64:等到您需要在模板中使用移动,该模板可以使用vector 或int 作为模板类型。除此之外,相同的参数适用于用户定义的类型。
  • 您通常在使用 ADL 之前声明 using std::move;。如果您尊重正确的模式,这些错误对我来说似乎是虚假的。
【解决方案3】:

它与实用程序中定义的移动功能相同。 http://en.cppreference.com/w/cpp/utility/move 但是为了代码清晰,您可以编写 std::move

【讨论】:

    猜你喜欢
    • 2014-02-16
    • 2021-09-07
    • 2012-10-24
    • 2021-12-19
    • 2021-05-07
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多