繁体   English   中英

移动构造函数和char数组参数

[英]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;

对所有编译器都是非法的。 datavar是数组(或对数组的引用),并且数组不可分配。 例如, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM