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) )
不满意? (也许这段代码毫无意义)
答案 0 :(得分:2)
您可以使用<algorithm>
标题中的std::move算法。
auto it = std::move(data, data + T, var);
检查T
是否不大于100.但移动char
并没有比复制更多的好处。
答案 1 :(得分:2)
该行
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;
引发的错误如下:
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
Visual Studio:
error C2440: '=' : cannot convert from 'int' to 'char [100]'