C++ cli 列表而非数组的pin_ptr

C++ cli 列表而非数组的pin_ptr,c++-cli,C++ Cli,我对cli::数组类型使用pin_ptr,一切正常 对于我认为是一个连续内存块的System::Collection::Generic::List,也可以这样做吗 显而易见的 List<double>^ stuff = gcnew List<double>( 10 ); cli::pin_ptr<double> resultPtr = &stuff[ 0 ]; List^stuff=gcnewlist(10); cli::pin_ptr resul

我对cli::数组类型使用pin_ptr,一切正常

对于我认为是一个连续内存块的System::Collection::Generic::List,也可以这样做吗

显而易见的

List<double>^ stuff = gcnew List<double>( 10 );

cli::pin_ptr<double> resultPtr = &stuff[ 0 ];
List^stuff=gcnewlist(10);
cli::pin_ptr resultPtr=&stuff[0];
给出一个编译器错误“error C2102:”&“requires l-value”,可能是因为索引属性返回的内容不是l-value!那么,还有其他方法可以做到这一点吗。我也玩过interior_ptr,但还没有发现任何有效的东西


我知道我可以打电话给名单上的ToArray,但关键是不要到处抄袭

不,这是不可能的

诚然,列表确实在幕后使用数组,但
[]
操作符不同。对于数组,
[]
是简单的指针数学,但是对于列表,
[]
是一个完整的方法调用。这就是
&
不起作用的原因:您可以获取数组位置的地址,但不能获取从方法返回的值的地址

可以这样想:如果他们愿意,他们可以在不更改其外部接口的情况下更改
List
的实现。可以更改列表以将列表内容存储在内存gzip压缩中。在这种情况下,
stuff[0]
是由执行解压缩的
[]
方法动态生成的,因此没有单个内存位置包含
stuff[0]

编辑
是的,在List类内部,内容在内存中是连续的。您可以在Microsoft提供的中看到这一点。但是,List类不会将该数组公开:List类的公共接口仅是public方法和属性。公共方法和属性表示一个约定,并且存储值的数组不是该约定的一部分。微软永远不会这样做,但他们可以做一个列表的gzip压缩实现,并且列表类的公共契约不会改变。您应该只将代码写入类的公共方法和属性,而不写入可能随时更改的内部。

有趣的是,您的回答似乎表明列表在内存中可能不连续。然而,这似乎强烈暗示了这一点。你知道微软是否有明确的答案吗?“是的,它是连续的”或“现在可能是,但我们保留将来更改的权利”是的,它是连续的,微软不会更改它,但如果他们更改了,它不会被视为破坏性的更改。请参见编辑。值得注意的是,文档中的一部分内容是O(1)访问,因此这在某种程度上意味着它是一个连续的块(因此它们永远不会gzip内部)。最终,美国CLR程序员依靠JIT的“智慧”来优化这些低级细节,而最终汇编代码的功能与我们使用指针进行优化的功能基本相同。