使用move()而非std::move()有哪些潜在问题?

4
当使用新的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()就是有问题的。 - Griwes
3个回答

6
ADL只会在参数类型也在std中的情况下查找std中的内容。
如果有另一个命名空间中也称为move的符号正在使用,则编译器将不知道您指的是哪一个。现在可能没有,但未来的更改可能会带来一个。
此外,始终使用std::使得后来阅读您的代码的人更容易理解。这清楚地表明它不是您自己定义或从另一个库中包含的move。如果他们以前没有听说过(相对较新的)std::move,那么这将非常有用。

使用ADL是扩大查找范围的整个目的,这是一种期望的效果。参见整个boost::swap的想法。我想移动没有必要重新定义,因为它有一个通用实现。如此之多,它甚至可以成为一个关键字。但这是一个非常特殊的情况,不能作为反对“启用ADL模式”的普遍情况的例子。 - v.oddou

4

一定要使用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

2
@Mr.C64:等到你需要在一个可以使用“vector”或“int”作为模板类型的模板中使用move时,再等待吧。除此之外,对于用户定义的类型,同样适用相同的参数。 - Danvil
通常在使用ADL之前,您需要声明using std::move;。如果您遵循正确的模式,这些错误看起来似乎是虚假的。 - v.oddou

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接