2

以下は、単純な C++/CLI の例です。

// TestCLR.cpp : main project file.

#include "stdafx.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    System::Collections::Generic::List<String^> TestList;

    for(int i = 0; i < 10 ; i++)
    {
        TestList.Add(i.ToString());
    }

    for each(String^% st in TestList)
    {
        st += "TEST";
        Console::WriteLine(st);
    }

    for each(String^ st in TestList)
    {
        Console::WriteLine(st);
    }

    return 0;
}

次の出力が得られます。

0TEST
1TEST
2TEST
3TEST
4TEST
5TEST
6TEST
7TEST
8TEST
9TEST
0
1
2
3
4
5
6
7
8
9

つまり、追跡ポインターを使用してその値を「TEST」に変更しても、TestList内の値は変更されません。

値が永続的に変更されるようにするには、上記のスニペットで何を変更する必要がありますか?

4

2 に答える 2

1

ここではコンパイラからの助けは得られていません。これはC#のCS1656エラーですが、C ++/CLIコンパイラは診断を提供するのを忘れています。

foreach反復変数は、IEnumerable<T>::Currentプロパティのエイリアスです。ゲッターだけがあり、セッターはありません。したがって、基になるコレクションを更新することはできません。ここでは、プレーンなfor()ループを使用する必要があります。

于 2012-05-28T19:41:20.770 に答える
1

プロパティを使用してSystem::Collections::Generic::Listアイテムにアクセスする があります。追跡参照をプロパティにバインドすることはできません。代わりに、値の一時的なコピーへの参照になります。

そのコードは配列に対しては機能しますがforeach、コンテナー内の要素をその場で変更するために使用することはできません。リスト要素を上書きするにはインデックスが必要なので、for ループが必要です。

for(int i = 0, cnt = TestList.Count; i < cnt; ++i)
{
    TestList[i] += "TEST";
    Console::WriteLine(TestList[i]);

    // doesn't work right: String^% st = TestList[i];
    // since TestList[i] is not an lvalue, it's a function call to a getter method
}

非 const 参照を一時オブジェクトにバインドしていることを示すコンパイラ警告が表示されませんでしたか?

于 2012-05-28T19:11:04.397 に答える