[英]Move constructor and char array argument
struct Foo
{
char data[100];
template<int T>
Foo(char (&&var)[T])
{
data = std::move(var);
var = 0;
}
};
int main()
{
char v[100];
//..init v
Foo f( std::move(v) ); //error C2664: 'Foo::Foo<100>(char (&&)[100])' : cannot convert parameter 1 from 'char [100]' to 'char (&&)[100]'
return 0;
}
我不明白为什么MSVC对Foo f( std::move(v) )
不满意? (也许这段代码毫无意义)
您可以使用<algorithm>
标头中的std :: move算法。
auto it = std::move(data, data + T, var);
在检查T
不大于100之后。移动char
没有比复制更多的好处。
这条线
Foo f( std::move(v) );
对GCC,Clang和Intel来说是合法的。 然而,Visual Studio抱怨和收益
error C2664: 'Foo::Foo(const Foo &)' : cannot convert parameter 2 from 'char [100]' to 'char (&&)[100]'
1> You cannot bind an lvalue to an rvalue reference
这对我来说似乎是个错误。 实际上, v
是一个左值,但是std::move
将它转换为右值引用。
由于字符数组不可移动,虽然合法,但我没有看到通过右值引用来获取它们的用处。 如果你真的想要编译代码,一个解决方法是使f
采用常规(左值)引用并删除调用站点上的std::move
。 或者甚至更好,让f
取一个指向char*
的指针( f
不需要是模板)。 在这种情况下,调用f(v)
将v[0]
的地址(即v
的第一个元素)传递给f
。 这就是所谓的数组到指针转换,它由编译器隐式执行。
但是,正如其他人所指出的那样
data = std::move(var);
var = 0;
对所有编译器都是非法的。 data
和var
是数组(或对数组的引用),并且数组不可分配。 例如, var = 0;
引发的错误var = 0;
每个编译器如下:
GCC:
error: incompatible types in assignment of 'int' to 'char [100]'
铛:
error: array type 'char [100]' is not assignable
英特尔:
error: expression must be a modifiable lvalue
视觉工作室:
error C2440: '=' : cannot convert from 'int' to 'char [100]'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.