C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突
C++ compiling error due to a conflict between the movement constructor and other non-movement one when using std::move
我正在对移动语义进行一些"实验",以便完全理解它。我已经到了我不完全理解的地步。这是因为在使用std::move
时似乎与 A::A(B b)
和 A::A(B &&b)
这样的构造函数存在冲突。下面是解释这一点的代码:
struct Item {
Item() { }
Item(const Item &other) {
std::cout << "Item::Item(const Item& )n";
}
};
struct Container {
Container(Item i) {
std::cout << "Container::Container(Item )n";
}
Container(Item &&i) {
std::cout << "Container::Container(Item&& )n";
}
};
int main() {
Item i;
Container c(std::move(i));
return 0;
}
尝试编译上述代码时,显示以下错误:
error C2668: 'Container::Container' : ambiguous call to overloaded function
1> c:usersxe74139documentsvisual studio 2012projectsproject1project1maincpp.cpp(21): could be 'Container::Container(Item &&)'
1> c:usersxe74139documentsvisual studio 2012projectsproject1project1maincpp.cpp(17): or 'Container::Container(Item)'
我知道构造函数Container(Item i)
根本没有意义,但我仍然不明白为什么编译器C++两个Container
构造函数之间看到冲突。
为什么它不能确定Container c(i)
用于呼叫Container(Item)
,Container c(std::move(i))
用于呼叫Container(Item &&)
?
编辑:或者,换句话说,为什么构造函数Container(Item)
对像Container c(std::move(i))
这样的调用有效?
据我所知,这是因为参数首先被评估,然后通过。一旦它被传递,它就是任何r-value
,你的两个构造函数都可以工作。我不确定是否有可能出现这样的过载,从我的角度来看这是没有意义的。
为什么不呢?好吧,您正在尝试定义一个强制元素移动的容器。从设计的角度来看,您必须考虑使用该代码的人可能不希望数据"被盗"(移动(。我认为在这种情况下,拥有以下内容会更有意义:
struct Item {
Item() { }
Item(const Item &other) {
std::cout << "Item::Item(const Item& )n";
}
Item(Item &&other) {
std::cout << "Item::Item(Item&&)n";
}
};
这种重载更有意义 - 您将明确说明何时要移动对象以及何时复制对象(这里有一个默认move
,但这种方式使其更加明显(。现在你只需要
Container(Item i);
(没有其他构造函数(并调用它
Container c(std::move(i));
是我们期望的 - 而不是复制i
,你明确表示你想要移动它,i
负责处理这个问题。
为什么构造函数 Container(Item( 对像 Container c(std::move(i(( 这样的调用有效?
因为当给定std::move(i)
的结果(这是一个Item&&
(时,您可以构造一个Item
。
就像 Howard Hinnant 在评论中所说的那样 - Item
vs Item&
是一样的 - 你可以在传递另一个时构造一个,所以如果你定义了这两个构造函数,你就创建了友好。
- "error: no matching function for call to"构造函数错误
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 选择要调用的构造函数
- 如何委托派生类使用其父构造函数?
- 构造函数正在调用一个使用当前类类型的函数
- 没有用于初始化C++中的变量模板的匹配构造函数
- 初始化具有非默认构造函数的std::数组项的更好方法
- 当从函数参数中的临时值调用复制构造函数时
- 在c++构造函数中使用随机字符串生成器
- 一对向量构造函数:初始值设定项列表与显式构造
- 从构造函数抛出异常时如何克服内存泄漏
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 具有默认模板类型的默认构造函数的类型推导
- 使用dynamic_cast和构造函数时出错
- 在c++中使用向量时,如何调用构造函数和析构函数
- C++编译错误是由于使用 std::move 时运动构造函数与其他非运动构造函数之间的冲突