1
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) )?(也许这段代码毫无意义)

4

2 回答 2

2

您可以使用标头中的std::move算法<algorithm>

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

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

于 2013-03-26T16:30:47.697 回答
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]vf

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

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

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

视觉工作室:

error C2440: '=' : cannot convert from 'int' to 'char [100]'
于 2013-03-26T19:53:59.260 回答