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、右辺値参照にキャストします。

char の配列は移動できないため、正当ではありますが、右辺値参照で配列を取得する用途はあまりありません。本当にコードをコンパイルしたい場合は、回避策としてf、通常の (左辺値) 参照を取得std::moveし、呼び出しサイトで を削除します。または、さらに良いことに、 (はテンプレートである必要はありません)fへのポインターを取得します。この場合、呼び出しは のアドレス(つまり の最初の要素) を に渡します。これは、コンパイラによって暗黙的に実行される、いわゆる配列からポインタへの変換です。char*ff(v)v[0]vf

ただし、他の人が指摘したように、行

    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

ビジュアルスタジオ:

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