【问题标题】:Move constructor and char array argument移动构造函数和 char 数组参数
【发布时间】:2013-03-16 12:37:45
【问题描述】:
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) ) 这条线不满意? (可能这段代码没有意义)

【问题讨论】:

  • 你究竟是如何移动一个数组的?您可以将一个数组的元素移动到另一个数组,但不能移动数组本身。
  • 仅用于教育目的
  • 我认为编译器抱怨它无法创建对数组的右值引用。这只是谷歌搜索“&& C++11”的猜测,因为我对 C++11 几乎一无所知。

标签: c++ visual-c++ c++11 move move-semantics


【解决方案1】:

您可以使用std::move 算法,来自&lt;algorithm&gt; 标头。

auto it = std::move(data, data + T, var);

在检查 T 不大于 100 之后。但移动 char 与仅复制相比并没有太多好处。

【讨论】:

    【解决方案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。这就是所谓的 array-to-pointer 转换,它由编译器隐式执行。

    但是,正如其他人指出的那样,这些行

        data = std::move(var);
        var = 0;
    

    对于所有编译器都是非法的。 datavar 是数组(或对数组的引用),数组不可赋值。比如每个编译器var = 0;报错如下:

    海合会:

    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]'
    

    【讨论】:

    • 在谷歌上搜索相同的问题时找到了这个答案。我不清楚,在阅读之后,在这样的类中使用移动构造函数做什么?我们要完全删除它吗?我是否仍然实现它,但是在移动构造函数中 strcpy char 数组?您已经进行了解释,但并没有真正说明要做什么。
    • @ChristopherPisz 实际上,我不会添加这个移动构造函数。 (请参阅 OP 中的 comment。)作者说问题是针对 "educational purpose" 的,这让我将问题解释为“为什么编译器会抱怨?”而不是“这样的构造函数的合理实现是什么?”。
    猜你喜欢
    • 2016-09-02
    • 2015-04-26
    • 1970-01-01
    • 2016-06-20
    • 2015-11-19
    • 2011-05-22
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多