【发布时间】:2021-02-08 09:32:08
【问题描述】:
我正在创建一个使用通用转发的库组件。 这在大多数情况下都可以正常工作,但我遇到过我们的 linux 构建(看似)错误地使用复制构造函数而不是移动构造函数的情况。
我能够使用 MVE 在 gcc 7.5(与我们的 linux 构建平台相同)上的 godbolt 中重现此内容:
#include <iostream>
using namespace std;
struct A
{
A(){}
A(const A&) = delete;
A(A&& other){ cout << "move A " << endl; }
};
template<class T>
struct B
{
template<class U = T>
B(U&& other)
: m_a(std::forward<U>(other))
{
cout << "forward T into B " << endl;
}
T m_a;
};
B<A> foo(A a)
{
return a;
//return std::move(a);
}
int main()
{
A a;
auto b = foo(std::move(a));
}
为了清楚起见,我添加了不可编译的版本来说明问题。
现在,据我所知,在这种情况下我不能使用 (N)RVO,因此移动本身并不是错误的,但我宁愿避免编写 return move(...); 当使用 gcc 8.1(或相对较新的 MSVC)编译它时,它确实使用了没有移动的移动构造函数。那么这只是一个编译器问题还是我需要改进我的“B”结构来处理这种情况?
【问题讨论】:
-
该示例应该重现什么问题?链接的godbolt编译没有错误。
-
链接的godbolt有编译返回std::move(a);我现在添加了非编译返回 a;希望这更清楚。
-
我建议相应地更改问题中的代码。
-
好的,完成。希望这能更清楚地说明问题。简而言之,我想在我的回归中避免搬家。